~ubuntu-branches/ubuntu/lucid/graphviz/lucid-security

« back to all changes in this revision

Viewing changes to tools/vmalloc/vmpool.c

  • Committer: Bazaar Package Importer
  • Author(s): Stephen M Moraco
  • Date: 2002-02-05 18:52:12 UTC
  • Revision ID: james.westby@ubuntu.com-20020205185212-8i04c70te00rc40y
Tags: upstream-1.7.16
ImportĀ upstreamĀ versionĀ 1.7.16

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include        "vmhdr.h"
 
2
 
 
3
#define POOLFREE        0x55555555L     /* block free indicator  */
 
4
 
 
5
/*      Method for pool allocation.
 
6
**      All elements in a pool have the same size.
 
7
**      The following fields of Vmdata_t are used as:
 
8
**              pool:   size of a block.
 
9
**              free:   list of free blocks.
 
10
**
 
11
**      Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
 
12
*/
 
13
 
 
14
#if __STD_C
 
15
static Void_t* poolalloc(Vmalloc_t* vm, reg size_t size)
 
16
#else
 
17
static Void_t* poolalloc(vm, size )
 
18
Vmalloc_t*      vm;
 
19
reg size_t      size;
 
20
#endif
 
21
{
 
22
        reg Vmdata_t*   vd = vm->data;
 
23
        reg Block_t     *tp, *next;
 
24
        reg size_t      s;
 
25
        reg Seg_t*      seg;
 
26
        reg int         local;
 
27
 
 
28
        if(size <= 0)
 
29
                return NIL(Void_t*);
 
30
        else if(size != vd->pool)
 
31
        {       if(vd->pool <= 0)
 
32
                        vd->pool = size;
 
33
                else    return NIL(Void_t*);
 
34
        }
 
35
 
 
36
        if(!(local = vd->mode&VM_TRUST) )
 
37
        {       if(ISLOCK(vd,0))
 
38
                        return NIL(Void_t*);
 
39
                SETLOCK(vd,0);
 
40
        }
 
41
 
 
42
        if((tp = vd->free) ) /* there is a ready free block */
 
43
        {       vd->free = SEGLINK(tp);
 
44
                goto done;
 
45
        }
 
46
 
 
47
        size = ROUND(size,ALIGN);
 
48
 
 
49
        /* look thru all segments for a suitable free block */
 
50
        for(tp = NIL(Block_t*), seg = vd->seg; seg; seg = seg->next)
 
51
        {       if((tp = seg->free) &&
 
52
                   (s = (SIZE(tp) & ~BITS) + sizeof(Head_t)) >= size )
 
53
                        goto has_blk;
 
54
        }
 
55
 
 
56
        for(;;) /* must extend region */
 
57
        {       if((tp = (*_Vmextend)(vm,ROUND(size,vd->incr),NIL(Vmsearch_f))) )
 
58
                {       s = (SIZE(tp) & ~BITS) + sizeof(Head_t);
 
59
                        seg = SEG(tp);
 
60
                        goto has_blk;
 
61
                }
 
62
                else if(vd->mode&VM_AGAIN)
 
63
                        vd->mode &= ~VM_AGAIN;
 
64
                else    goto done;
 
65
        }
 
66
 
 
67
has_blk: /* if get here, (tp, s, seg) must be well-defined */
 
68
        next = (Block_t*)((Vmuchar_t*)tp+size);
 
69
        if((s -= size) <= (size + sizeof(Head_t)) )
 
70
        {       for(; s >= size; s -= size)
 
71
                {       SIZE(next) = POOLFREE;
 
72
                        SEGLINK(next) = vd->free;
 
73
                        vd->free = next;
 
74
                        next = (Block_t*)((Vmuchar_t*)next + size);
 
75
                }
 
76
                seg->free = NIL(Block_t*);
 
77
        }
 
78
        else
 
79
        {       SIZE(next) = s - sizeof(Head_t);
 
80
                SEG(next) = seg;
 
81
                seg->free = next;
 
82
        }
 
83
 
 
84
done:
 
85
        if(!local && (vd->mode&VM_TRACE) && _Vmtrace && tp)
 
86
                (*_Vmtrace)(vm,NIL(Vmuchar_t*),(Vmuchar_t*)tp,vd->pool,0);
 
87
 
 
88
        CLRLOCK(vd,0);
 
89
        return (Void_t*)tp;
 
90
}
 
91
 
 
92
#if __STD_C
 
93
static long pooladdr(Vmalloc_t* vm, reg Void_t* addr)
 
94
#else
 
95
static long pooladdr(vm, addr)
 
96
Vmalloc_t*      vm;
 
97
reg Void_t*     addr;
 
98
#endif
 
99
{
 
100
        reg Block_t     *bp, *tp;
 
101
        reg Vmuchar_t   *laddr, *baddr;
 
102
        reg size_t      size;
 
103
        reg Seg_t*      seg;
 
104
        reg long        offset;
 
105
        reg Vmdata_t*   vd = vm->data;
 
106
        reg int         local;
 
107
 
 
108
        if(!(local = vd->mode&VM_TRUST))
 
109
        {       GETLOCAL(vd,local);
 
110
                if(ISLOCK(vd,local))
 
111
                        return -1L;
 
112
                SETLOCK(vd,local);
 
113
        }
 
114
 
 
115
        offset = -1L;
 
116
        for(seg = vd->seg; seg; seg = seg->next)
 
117
        {       laddr = (Vmuchar_t*)SEGBLOCK(seg);
 
118
                baddr = seg->baddr-sizeof(Head_t);
 
119
                if((Vmuchar_t*)addr < laddr || (Vmuchar_t*)addr >= baddr)
 
120
                        continue;
 
121
 
 
122
                /* the block that has this address */
 
123
                size = ROUND(vd->pool,ALIGN);
 
124
                tp = (Block_t*)(laddr + (((Vmuchar_t*)addr-laddr)/size)*size );
 
125
 
 
126
                /* see if this block has been freed */
 
127
                if(SIZE(tp) == POOLFREE) /* may be a coincidence - make sure */
 
128
                        for(bp = vd->free; bp; bp = SEGLINK(bp))
 
129
                                if(bp == tp)
 
130
                                        goto done;
 
131
 
 
132
                offset = (Vmuchar_t*)addr - (Vmuchar_t*)tp;
 
133
                goto done;
 
134
        }
 
135
 
 
136
done :
 
137
        CLRLOCK(vd,local);
 
138
        return offset;
 
139
}
 
140
 
 
141
#if __STD_C
 
142
static int poolfree(reg Vmalloc_t* vm, reg Void_t* data )
 
143
#else
 
144
static int poolfree(vm, data)
 
145
reg Vmalloc_t*  vm;
 
146
reg Void_t*     data;
 
147
#endif
 
148
{
 
149
        reg Block_t*    bp;
 
150
        reg Vmdata_t*   vd = vm->data;
 
151
        reg int         local;
 
152
 
 
153
        if(!data)
 
154
                return 0;
 
155
 
 
156
        if(!(local = vd->mode&VM_TRUST))
 
157
        {       if(ISLOCK(vd,0) || vd->pool <= 0)
 
158
                        return -1;
 
159
 
 
160
                if(KPVADDR(vm,data,pooladdr) != 0)
 
161
                {       if(vm->disc->exceptf)
 
162
                                (void)(*vm->disc->exceptf)(vm,VM_BADADDR,data,vm->disc);
 
163
                        return -1;
 
164
                }
 
165
 
 
166
                SETLOCK(vd,0);
 
167
        }
 
168
 
 
169
        bp = (Block_t*)data;
 
170
        SIZE(bp) = POOLFREE;
 
171
        SEGLINK(bp) = vd->free;
 
172
        vd->free = bp;
 
173
 
 
174
        if(!local && (vd->mode&VM_TRACE) && _Vmtrace)
 
175
                (*_Vmtrace)(vm, (Vmuchar_t*)data, NIL(Vmuchar_t*), vd->pool, 0);
 
176
 
 
177
        CLRLOCK(vd,local);
 
178
        return 0;
 
179
}
 
180
 
 
181
#if __STD_C
 
182
static Void_t* poolresize(Vmalloc_t* vm, Void_t* data, size_t size, int type )
 
183
#else
 
184
static Void_t* poolresize(vm, data, size, type )
 
185
Vmalloc_t*      vm;
 
186
Void_t*         data;
 
187
size_t          size;
 
188
int             type;
 
189
#endif
 
190
{
 
191
        reg Vmdata_t*   vd = vm->data;
 
192
 
 
193
        NOTUSED(type);
 
194
 
 
195
        if(!data)
 
196
        {       if((data = poolalloc(vm,size)) && (type&VM_RSZERO) )
 
197
                {       reg int *d = (int*)data, *ed = (int*)((char*)data+size);
 
198
                        do { *d++ = 0;} while(d < ed);
 
199
                }
 
200
                return data;
 
201
        }
 
202
        if(size == 0)
 
203
        {       (void)poolfree(vm,data);
 
204
                return NIL(Void_t*);
 
205
        }
 
206
 
 
207
        if(!(vd->mode&VM_TRUST) )
 
208
        {       if(ISLOCK(vd,0) )
 
209
                        return NIL(Void_t*);
 
210
 
 
211
                if(size != vd->pool || KPVADDR(vm,data,pooladdr) != 0)
 
212
                {       if(vm->disc->exceptf)
 
213
                                (void)(*vm->disc->exceptf)(vm,VM_BADADDR,data,vm->disc);
 
214
                        return NIL(Void_t*);
 
215
                }
 
216
 
 
217
                if((vd->mode&VM_TRACE) && _Vmtrace)
 
218
                        (*_Vmtrace)(vm, (Vmuchar_t*)data, (Vmuchar_t*)data, size, 0);
 
219
        }
 
220
 
 
221
        return data;
 
222
}
 
223
 
 
224
#if __STD_C
 
225
static long poolsize(Vmalloc_t* vm, Void_t* addr)
 
226
#else
 
227
static long poolsize(vm, addr)
 
228
Vmalloc_t*      vm;
 
229
Void_t*         addr;
 
230
#endif
 
231
{
 
232
        return pooladdr(vm,addr) == 0 ? (long)vm->data->pool : -1L;
 
233
}
 
234
 
 
235
#if __STD_C
 
236
static int poolcompact(Vmalloc_t* vm)
 
237
#else
 
238
static int poolcompact(vm)
 
239
Vmalloc_t*      vm;
 
240
#endif
 
241
{
 
242
        reg Block_t*    fp;
 
243
        reg Seg_t       *seg, *next;
 
244
        reg size_t      s;
 
245
        reg Vmdata_t*   vd = vm->data;
 
246
 
 
247
        if(!(vd->mode&VM_TRUST))
 
248
        {       if(ISLOCK(vd,0))
 
249
                        return -1;
 
250
                SETLOCK(vd,0);
 
251
        }
 
252
 
 
253
        for(seg = vd->seg; seg; seg = next)
 
254
        {       next = seg->next;
 
255
 
 
256
                if(!(fp = seg->free))
 
257
                        continue;
 
258
 
 
259
                seg->free = NIL(Block_t*);
 
260
                if(seg->size == (s = SIZE(fp)&~BITS))
 
261
                        s = seg->extent;
 
262
                else    s += sizeof(Head_t);
 
263
 
 
264
                if((*_Vmtruncate)(vm,seg,s,1) < 0)
 
265
                        seg->free = fp;
 
266
        }
 
267
 
 
268
        if((vd->mode&VM_TRACE) && _Vmtrace)
 
269
                (*_Vmtrace)(vm, (Vmuchar_t*)0, (Vmuchar_t*)0, 0, 0);
 
270
 
 
271
        CLRLOCK(vd,0);
 
272
        return 0;
 
273
}
 
274
 
 
275
#if __STD_C
 
276
static Void_t* poolalign(Vmalloc_t* vm, size_t size, size_t align)
 
277
#else
 
278
static Void_t* poolalign(vm, size, align)
 
279
Vmalloc_t*      vm;
 
280
size_t          size;
 
281
size_t          align;
 
282
#endif
 
283
{
 
284
        NOTUSED(vm);
 
285
        NOTUSED(size);
 
286
        NOTUSED(align);
 
287
        return NIL(Void_t*);
 
288
}
 
289
 
 
290
/* Public interface */
 
291
static Vmethod_t _Vmpool =
 
292
{
 
293
        poolalloc,
 
294
        poolresize,
 
295
        poolfree,
 
296
        pooladdr,
 
297
        poolsize,
 
298
        poolcompact,
 
299
        poolalign,
 
300
        VM_MTPOOL
 
301
};
 
302
 
 
303
__DEFINE__(Vmethod_t*,Vmpool,&_Vmpool);