root/common/trunk/src/util.c @ 74

Revision 74, 6.6 KB (checked in by ucacoxh, 15 years ago)

- Removed debug message from purge string. Happy this works.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2 * FILE: util.c
3 * PROGRAM: RAT
4 * AUTHOR: Isidor Kouvelas + Colin Perkins + Mark Handley + Orion Hodson
5 *
6 * $Revision$
7 * $Date$
8 *
9 * Copyright (c) 1995-97 University College London
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, is permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 *    notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 *    notice, this list of conditions and the following disclaimer in the
19 *    documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 *    must display the following acknowledgement:
22 *      This product includes software developed by the Computer Science
23 *      Department at University College London
24 * 4. Neither the name of the University nor of the Department may be used
25 *    to endorse or promote products derived from this software without
26 *    specific prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 */
39
40#include "config_unix.h"
41#include "config_win32.h"
42#include "debug.h"
43#include "memory.h"
44#include "util.h"
45
46typedef struct s_block {
47        struct s_block  *next;
48} block;
49 
50#define BLOCK_SIZE            5
51#define SIZE_TO_INDEX(s)      (((s) - 1) >> BLOCK_SIZE)
52#define INDEX_TO_SIZE(i)      (((i) + 1) << BLOCK_SIZE)
53#define MAX_SIZE              (1 << 17)
54#define MAX_INDEX             SIZE_TO_INDEX(MAX_SIZE)
55 
56static block  *blocks[MAX_INDEX];
57static int     blocks_alloced;
58
59#ifdef DEBUG_MEM
60
61/* Block tracking for when things are going wrong */
62
63#define MAX_BLOCKS_OUT 1280
64static struct iovec blk_out[MAX_BLOCKS_OUT];
65static int          nblks_out;
66
67static int
68get_blk_idx_from_ptr(char *addr)
69{
70        int i;
71        for(i = 0; i < nblks_out; i++) {
72                if (blk_out[i].iov_base == addr) {
73                        return i;
74                }
75        }
76        return -1;
77}
78#endif /* DEBUG_MEM */
79 
80void *
81_block_alloc(unsigned int size, const char *filen, int line)
82{
83        int              i;
84        unsigned int    *c;
85        char            *p;
86
87        assert(size > 0);
88        assert(size < MAX_SIZE);
89
90        i = SIZE_TO_INDEX(size);
91 
92        if (blocks[i] != NULL) {
93                p = (char *)blocks[i];
94                blocks[i] = blocks[i]->next;
95        } else {
96#ifdef DEBUG_MEM_BREAK
97                /* This can only go here if this file is merged with memory.c! [oh] */
98                mem_item[naddr].blen = size;
99#endif /* DEBUG_MEM_BREAK */
100                p = (char *) _xmalloc(INDEX_TO_SIZE(i) + 8,filen,line);
101                *((int *)p) = INDEX_TO_SIZE(i);
102                p += 8;
103                blocks_alloced++;
104        }
105        c = (unsigned int *)((char *)p - 8);
106        if (size > *c) {
107                fprintf(stderr, "block_alloc: block is too small %d %d!\n", size, *c);
108        }
109#ifdef DEBUG_MEM
110        if (blocks_alloced == MAX_BLOCKS_OUT) {
111                debug_msg("Too many blocks allocated.\n");
112                xmemdmp();
113        }
114
115        blk_out[nblks_out].iov_base = (char*)c;
116        blk_out[nblks_out].iov_len  = size;
117        nblks_out++;
118#endif /* DEBUG_MEM */
119        c++;
120        *c = size;
121        assert(p != NULL);
122        return (void*)p;
123}
124
125void
126block_trash_check()
127{
128#ifdef DEBUG_MEM
129        int i,n,*c;
130        block *b;
131
132        for(i = 0; i<MAX_INDEX;i++) {
133                b = blocks[i];
134                n = 0;
135                while(b) {
136                        b = b->next;
137                        assert(n++ < blocks_alloced);
138                }
139        }
140        for (i = 0; i<nblks_out; i++) {
141                c = (int*)blk_out[i].iov_base;
142                c++;
143                assert((unsigned int)*c == (unsigned int)blk_out[i].iov_len);
144        }
145#endif  /* DEBUG_MEM */
146}
147
148void
149block_check(char *p)
150{
151#ifdef DEBUG_MEM
152        char *blk_base;
153        assert(p!=NULL);
154        blk_base = p-8;
155        assert(get_blk_idx_from_ptr(blk_base) != -1);
156#endif /* DEBUG_MEM */
157        UNUSED(p);
158}
159 
160void
161_block_free(void *p, int size, int line)
162{
163        int     i, *c;
164#ifdef DEBUG
165        block *bp;
166        int    n;
167#endif
168        UNUSED(line);
169
170        c = (int *)((char *)p - 8);
171
172#ifdef DEBUG_MEM
173        n = get_blk_idx_from_ptr((char*)c);
174        if (n == -1) {
175                debug_msg("Freeing block (addr 0x%x, %d bytes) that was not allocated with block_alloc(?)\n", (int)c, *(c+1));
176                xfree(c);
177                assert(n != -1);
178        }
179#endif
180
181        if (size > *c) {
182                fprintf(stderr, "block_free: block was too small! %d %d\n", size, *c);
183        }
184        c++;
185        if (size != *c) {
186                fprintf(stderr, "block_free: Incorrect block size given! %d %d\n", size, *c);
187                assert(size == *c);
188        }
189 
190        i = SIZE_TO_INDEX(size);
191#ifdef DEBUG
192        bp = blocks[i];
193        n = 0;
194        while(bp) {
195                if (bp == (block*)p) {
196                        debug_msg("already freed line %d\n", *((int *)p+1));
197                        assert(0);
198                }
199                bp = bp->next;
200                n++;
201        }
202        if (i >= 4) {
203                *((int*)p+1) = line;
204        }
205#endif /* DEBUG */
206        ((block *)p)->next = blocks[i];
207        blocks[i] = (block *)p;
208#ifdef DEBUG_MEM
209        c--;
210        i = get_blk_idx_from_ptr((char*)c);
211        assert(i != -1);
212        memmove(blk_out+i, blk_out + i + 1, sizeof(struct iovec) * (nblks_out - i));
213        nblks_out --;
214#endif /* DEBUG_MEM */
215}
216
217void
218block_release_all(void)
219{
220    int i;
221    char *p,*q;
222
223    printf("Freeing memory: "); fflush(stdout);
224    for(i=0;i<MAX_INDEX;i++) {
225        p = (char*)blocks[i];
226        while(p) {
227            q = (char*)((block*)p)->next;
228            xfree(p-8);
229            printf("+"); fflush(stdout);
230            p = q;
231        }
232    }
233    printf("\n");
234}
235
236void
237purge_chars(char *src, char *to_go)
238{
239        char *r, *w;
240        r = w = src;
241        while(*r) {
242                *w = *r;
243                if (!strchr(to_go, (int)*r)) {
244                        w++;
245                }
246                r++;
247        }
248        *w = '\0';
249}
Note: See TracBrowser for help on using the browser.