~vkolesnikov/pbxt/pbxt-07-diskfull

« back to all changes in this revision

Viewing changes to pbxt/src/c_heap.c

  • Committer: paul-mccullagh
  • Date: 2006-10-23 09:14:04 UTC
  • Revision ID: paul-mccullagh-918861e03d351978a9541168a96e58cc826734ee
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2005 SNAP Innovation GmbH
 
2
 *
 
3
 * PrimeBase XT
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License as published by
 
7
 * the Free Software Foundation; either version 2 of the License, or
 
8
 * (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software
 
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
18
 *
 
19
 * 2005-01-10   Paul McCullagh
 
20
 *
 
21
 * H&G2JCtL
 
22
 */
 
23
 
 
24
#include "xt_config.h"
 
25
 
 
26
#include "xt_heap.h"
 
27
#include "xt_thread.h"
 
28
 
 
29
#ifdef xt_heap_new
 
30
#undef xt_heap_new
 
31
#endif
 
32
 
 
33
typedef struct XTHeap {
 
34
        xt_rwlock_type          h_lock;                                 /* Prevent concurrent access to the heap memory: */
 
35
        u_int                                   h_ref_count;                    /* So we know when to free (EVERY pointer reference MUST be counted). */
 
36
        XTFinalizeFunc                  h_finalize;                             /* If non-NULL, call before freeing. */
 
37
        XTFinalizeFunc                  h_onrelease;                    /* If non-NULL, call on release. */
 
38
        union {
 
39
                double                          align_dummy;
 
40
                char                            h_data[XT_VAR_LENGTH];          /* This is the user memory */
 
41
        } x;
 
42
} XTHeapRec, *XTHeapPtr;
 
43
 
 
44
#ifdef DEBUG
 
45
xtPublic void *xt_mm_heap_new(XTThreadPtr self, size_t size, XTFinalizeFunc finalize, u_int line, char *file)
 
46
#else
 
47
xtPublic void *xt_heap_new(XTThreadPtr self, size_t size, XTFinalizeFunc finalize)
 
48
#endif
 
49
{
 
50
        XTHeapPtr       hp;
 
51
        
 
52
#ifdef DEBUG
 
53
        hp = xt_mm_calloc(self, offsetof(XTHeapRec, x.h_data) + size, line, file);
 
54
#else
 
55
        hp = xt_calloc(self, offsetof(XTHeapRec, x.h_data) + size);
 
56
#endif
 
57
        if (!hp)
 
58
                return NULL;
 
59
 
 
60
        try_(a) {
 
61
                xt_init_rwlock(self, &hp->h_lock);
 
62
        }
 
63
        catch_(a) {
 
64
                xt_free(self, hp);
 
65
                throw_();
 
66
        }
 
67
        cont_(a);
 
68
 
 
69
        hp->h_ref_count = 1;
 
70
        hp->h_finalize = finalize;
 
71
        hp->h_onrelease = NULL;
 
72
        return hp->x.h_data;
 
73
}
 
74
 
 
75
xtPublic void xt_check_heap(XTThreadPtr self, void *mem)
 
76
{
 
77
        char *hp = ((char *) mem - offsetof(XTHeapRec, x.h_data));
 
78
 
 
79
#ifdef DEBUG
 
80
        xt_mm_malloc_size(self, hp);
 
81
#endif
 
82
}
 
83
 
 
84
xtPublic void xt_heap_reference(XTThreadPtr self, void *mem)
 
85
{
 
86
        XTHeapPtr       hp = (XTHeapPtr) ((char *) mem - offsetof(XTHeapRec, x.h_data));
 
87
 
 
88
        xt_w_lock(self, &hp->h_lock);
 
89
        hp->h_ref_count++;
 
90
        xt_rw_unlock(self, &hp->h_lock);
 
91
}
 
92
 
 
93
xtPublic void xt_heap_release(XTThreadPtr self, void *mem)
 
94
{
 
95
        XTHeapPtr       hp;
 
96
        
 
97
        if (!mem)
 
98
                return;
 
99
        hp = (XTHeapPtr) ((char *) mem - offsetof(XTHeapRec, x.h_data));
 
100
#ifdef DEBUG
 
101
        xt_r_lock(NULL, &hp->h_lock);
 
102
        ASSERT(hp->h_ref_count != 0);
 
103
        xt_rw_unlock(self, &hp->h_lock);
 
104
#endif
 
105
        xt_w_lock(self, &hp->h_lock);
 
106
        if (hp->h_onrelease)
 
107
                (*hp->h_onrelease)(self, mem);
 
108
        if (hp->h_ref_count > 0) {
 
109
                hp->h_ref_count--;
 
110
                if (hp->h_ref_count == 0) {
 
111
                        if (hp->h_finalize)
 
112
                                (*hp->h_finalize)(self, mem);
 
113
                        xt_rw_unlock(self, &hp->h_lock);
 
114
                        xt_free(self, hp);
 
115
                        return;
 
116
                }
 
117
        }
 
118
        xt_rw_unlock(self, &hp->h_lock);
 
119
}
 
120
 
 
121
xtPublic void xt_heap_set_release_callback(XTThreadPtr self, void *mem, XTFinalizeFunc onrelease)
 
122
{
 
123
        XTHeapPtr       hp = (XTHeapPtr) ((char *) mem - offsetof(XTHeapRec, x.h_data));
 
124
 
 
125
        hp->h_onrelease = onrelease;
 
126
}
 
127
 
 
128
xtPublic u_int xt_heap_get_ref_count(struct XTThread *self, void *mem)
 
129
{
 
130
        XTHeapPtr       hp = (XTHeapPtr) ((char *) mem - offsetof(XTHeapRec, x.h_data));
 
131
 
 
132
        return hp->h_ref_count;
 
133
}
 
134
 
 
135
xtPublic void *xt_heap_rlock(XTThreadPtr th, void *mem)
 
136
{
 
137
        XTHeapPtr       hp = (XTHeapPtr) ((char *) mem - offsetof(XTHeapRec, x.h_data));
 
138
 
 
139
        return xt_r_lock(th, &hp->h_lock) ? mem : NULL;
 
140
}
 
141
 
 
142
xtPublic void *xt_heap_wlock(XTThreadPtr self, void *mem)
 
143
{
 
144
        XTHeapPtr       hp = (XTHeapPtr) ((char *) mem - offsetof(XTHeapRec, x.h_data));
 
145
 
 
146
        return xt_w_lock(self, &hp->h_lock) ? mem : NULL;
 
147
}
 
148
 
 
149
xtPublic void xt_heap_unlock(XTThreadPtr self, void *mem)
 
150
{
 
151
        XTHeapPtr       hp = (XTHeapPtr) ((char *) mem - offsetof(XTHeapRec, x.h_data));
 
152
 
 
153
        xt_rw_unlock(self, &hp->h_lock);
 
154
}
 
155