Synopsis - Cross-Reference

File: /src/Synopsis/gc/pcr_interface.c
  1/* 
  2 * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved.
  3 *
  4 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
  5 * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
  6 *
  7 * Permission is hereby granted to use or copy this program
  8 * for any purpose,  provided the above notices are retained on all copies.
  9 * Permission to modify the code and to distribute modified code is granted,
 10 * provided the above notices are retained, and a notice that the code was
 11 * modified is included with the above copyright notice.
 12 */
 13# include "private/gc_priv.h"
 14
 15# ifdef PCR
 16/*
 17 * Note that POSIX PCR requires an ANSI C compiler.  Hence we are allowed
 18 * to make the same assumption here.
 19 * We wrap all of the allocator functions to avoid questions of
 20 * compatibility between the prototyped and nonprototyped versions of the f
 21 */
 22# include "config/PCR_StdTypes.h"
 23# include "mm/PCR_MM.h"
 24# include <errno.h>
 25
 26# define MY_MAGIC 17L
 27# define MY_DEBUGMAGIC 42L
 28
 29void * GC_AllocProc(size_t size, PCR_Bool ptrFree, PCR_Bool clear )
 30{
 31    if (ptrFree) {
 32        void * result = (void *)GC_malloc_atomic(size);
 33        if (clear && result != 0) BZERO(result, size);
 34        return(result);
 35    } else {
 36        return((void *)GC_malloc(size));
 37    }
 38}
 39
 40void * GC_DebugAllocProc(size_t size, PCR_Bool ptrFree, PCR_Bool clear )
 41{
 42    if (ptrFree) {
 43        void * result = (void *)GC_debug_malloc_atomic(size, __FILE__,
 44        						     __LINE__);
 45        if (clear && result != 0) BZERO(result, size);
 46        return(result);
 47    } else {
 48        return((void *)GC_debug_malloc(size, __FILE__, __LINE__));
 49    }
 50}
 51
 52# define GC_ReallocProc GC_realloc
 53void * GC_DebugReallocProc(void * old_object, size_t new_size_in_bytes)
 54{
 55    return(GC_debug_realloc(old_object, new_size_in_bytes, __FILE__, __LINE__));
 56}
 57
 58# define GC_FreeProc GC_free
 59# define GC_DebugFreeProc GC_debug_free
 60
 61typedef struct {
 62  PCR_ERes (*ed_proc)(void *p, size_t size, PCR_Any data);
 63  GC_bool ed_pointerfree;
 64  PCR_ERes ed_fail_code;
 65  PCR_Any ed_client_data;
 66} enumerate_data;
 67
 68void GC_enumerate_block(struct hblk *h; enumerate_data * ed)
 69{
 70    register hdr * hhdr;
 71    register int sz;
 72    ptr_t p;
 73    ptr_t lim;
 74    word descr;
 75#   error This code was updated without testing.
 76#   error and its precursor was clearly broken.
 77    
 78    hhdr = HDR(h);
 79    descr = hhdr -> hb_descr;
 80    sz = hhdr -> hb_sz;
 81    if (descr != 0 && ed -> ed_pointerfree
 82    	|| descr == 0 && !(ed -> ed_pointerfree)) return;
 83    lim = (ptr_t)(h+1) - sz;
 84    p = (ptr_t)h;
 85    do {
 86        if (PCR_ERes_IsErr(ed -> ed_fail_code)) return;
 87        ed -> ed_fail_code =
 88            (*(ed -> ed_proc))(p, sz, ed -> ed_client_data);
 89        p+= sz;
 90    } while (p <= lim);
 91}
 92
 93struct PCR_MM_ProcsRep * GC_old_allocator = 0;
 94
 95PCR_ERes GC_EnumerateProc(
 96    PCR_Bool ptrFree,
 97    PCR_ERes (*proc)(void *p, size_t size, PCR_Any data),
 98    PCR_Any data
 99)
100{
101    enumerate_data ed;
102    
103    ed.ed_proc = proc;
104    ed.ed_pointerfree = ptrFree;
105    ed.ed_fail_code = PCR_ERes_okay;
106    ed.ed_client_data = data;
107    GC_apply_to_all_blocks(GC_enumerate_block, &ed);
108    if (ed.ed_fail_code != PCR_ERes_okay) {
109        return(ed.ed_fail_code);
110    } else {
111    	/* Also enumerate objects allocated by my predecessors */
112    	return((*(GC_old_allocator->mmp_enumerate))(ptrFree, proc, data));
113    }
114}
115
116void GC_DummyFreeProc(void *p) {}
117
118void GC_DummyShutdownProc(void) {}
119
120struct PCR_MM_ProcsRep GC_Rep = {
121	MY_MAGIC,
122	GC_AllocProc,
123	GC_ReallocProc,
124	GC_DummyFreeProc,  	/* mmp_free */
125	GC_FreeProc,  		/* mmp_unsafeFree */
126	GC_EnumerateProc,
127	GC_DummyShutdownProc	/* mmp_shutdown */
128};
129
130struct PCR_MM_ProcsRep GC_DebugRep = {
131	MY_DEBUGMAGIC,
132	GC_DebugAllocProc,
133	GC_DebugReallocProc,
134	GC_DummyFreeProc,  	/* mmp_free */
135	GC_DebugFreeProc,  		/* mmp_unsafeFree */
136	GC_EnumerateProc,
137	GC_DummyShutdownProc	/* mmp_shutdown */
138};
139
140GC_bool GC_use_debug = 0;
141
142void GC_pcr_install()
143{
144    PCR_MM_Install((GC_use_debug? &GC_DebugRep : &GC_Rep), &GC_old_allocator);
145}
146
147PCR_ERes
148PCR_GC_Setup(void)
149{
150    return PCR_ERes_okay;
151}
152
153PCR_ERes
154PCR_GC_Run(void)
155{
156
157    if( !PCR_Base_TestPCRArg("-nogc") ) {
158        GC_quiet = ( PCR_Base_TestPCRArg("-gctrace") ? 0 : 1 );
159        GC_use_debug = (GC_bool)PCR_Base_TestPCRArg("-debug_alloc");
160        GC_init();
161        if( !PCR_Base_TestPCRArg("-nogc_incremental") ) {
162            /*
163             * awful hack to test whether VD is implemented ...
164             */
165            if( PCR_VD_Start( 0, NIL, 0) != PCR_ERes_FromErr(ENOSYS) ) {
166	        GC_enable_incremental();
167	    }
168	}
169    }
170    return PCR_ERes_okay;
171}
172
173void GC_push_thread_structures(void)
174{
175    /* PCR doesn't work unless static roots are pushed.  Can't get here. */
176    ABORT("In GC_push_thread_structures()");
177}
178
179# endif