summaryrefslogtreecommitdiff
path: root/pcr_interface.c
blob: 573d34f7da1e9537db8a637322bfc323681f17cf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/* 
 * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
 * Copyright (c) 1991, 1992 by Xerox Corporation.  All rights reserved.
 *
 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
 * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
 *
 * Permission is hereby granted to copy this garbage collector for any purpose,
 * provided the above notices are retained on all copies.
 */
# include "gc_private.h"

# ifdef PCR
/*
 * Note that POSIX PCR requires an ANSI C compiler.  Hence we are allowed
 * to make the same assumption here.
 * We wrap all of the allocator functions to avoid questions of
 * compatibility between the prototyped and nonprototyped versions of the f
 */
# include "pcr/mm/PCR_MM.h"

# define MY_MAGIC 17L

void * GC_AllocProc(size_t size, PCR_Bool ptrFree, PCR_Bool clear )
{
    if (ptrFree) {
        void * result = (void *)GC_malloc_atomic(size);
        if (clear && result != 0) bzero(result, size);
        return(result);
    } else {
        return((void *)GC_malloc(size));
    }
}

# define GC_ReallocProc GC_realloc

# define GC_FreeProc GC_free

typedef struct {
  PCR_ERes (*ed_proc)(void *p, size_t size, PCR_Any data);
  bool ed_pointerfree;
  PCR_ERes ed_fail_code;
  PCR_Any ed_client_data;
} enumerate_data;

void GC_enumerate_block(h, ed)
register struct hblk *h;
enumerate_data * ed;
{
    register hdr * hhdr;
    register int sz;
    word *p;
    word * lim;
    
    hhdr = HDR(h);
    sz = hhdr -> hb_sz;
    if (sz >= 0 && ed -> ed_pointerfree
    	|| sz <= 0 && !(ed -> ed_pointerfree)) return;
    if (sz < 0) sz = -sz;
    lim = (word *)(h+1) - sz;
    p = (word *)h;
    do {
        if (PCR_ERes_IsErr(ed -> ed_fail_code)) return;
        ed -> ed_fail_code =
            (*(ed -> ed_proc))(p, WORDS_TO_BYTES(sz), ed -> ed_client_data);
        p+= sz;
    } while (p <= lim);
}

struct PCR_MM_ProcsRep * GC_old_allocator = 0;

PCR_ERes GC_EnumerateProc(
    PCR_Bool ptrFree,
    PCR_ERes (*proc)(void *p, size_t size, PCR_Any data),
    PCR_Any data
)
{
    enumerate_data ed;
    
    ed.ed_proc = proc;
    ed.ed_pointerfree = ptrFree;
    ed.ed_fail_code = PCR_ERes_okay;
    ed.ed_client_data = data;
    GC_apply_to_all_blocks(GC_enumerate_block, &ed);
    if (ed.ed_fail_code != PCR_ERes_okay) {
        return(ed.ed_fail_code);
    } else {
    	/* Also enumerate objects allocated by my predecessors */
    	return((*(GC_old_allocator->mmp_enumerate))(ptrFree, proc, data));
    }
}

void GC_DummyFreeProc(void *p) {};

void GC_DummyShutdownProc(void) {};

struct PCR_MM_ProcsRep GC_Rep = {
	MY_MAGIC,
	GC_AllocProc,
	GC_ReallocProc,
	GC_DummyFreeProc,  	/* mmp_free */
	GC_FreeProc,  		/* mmp_unsafeFree */
	GC_EnumerateProc,
	GC_DummyShutdownProc	/* mmp_shutdown */
};

void GC_pcr_install()
{
    PCR_MM_Install(&GC_Rep, &GC_old_allocator);
}
# endif