~ubuntu-branches/ubuntu/saucy/drizzle/saucy-proposed

« back to all changes in this revision

Viewing changes to plugin/pbms/src/cslib/CSMemory.cc

  • Committer: Package Import Robot
  • Author(s): Clint Byrum
  • Date: 2012-06-19 10:46:49 UTC
  • mfrom: (1.2.11) (2.1.16 sid)
  • Revision ID: package-import@ubuntu.com-20120619104649-9ij634mxm4x8pp4l
Tags: 1:7.1.36-stable-1ubuntu1
* Merge from Debian unstable. (LP: #987575)
  Remaining changes:
  - Added upstart script.
* debian/drizzle.upstart: dropped logger since upstart logs job
  output now.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2008 PrimeBase Technologies GmbH, Germany
2
 
 *
3
 
 * PrimeBase Media Stream for MySQL
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
 
 *
19
 
 * Original author: Paul McCullagh (H&G2JCtL)
20
 
 * Continued development: Barry Leslie
21
 
 *
22
 
 * 2007-06-15
23
 
 *
24
 
 * CORE SYSTEM:
25
 
 * Memory allocation
26
 
 *
27
 
 * For debugging memory leaks search for "DEBUG-BREAK-POINT" and watch mm_tracking_id
28
 
 */
29
 
 
30
 
#include "CSConfig.h"
31
 
 
32
 
#include <assert.h>
33
 
#include <string.h>
34
 
#include <stddef.h>
35
 
#include <stdlib.h>
36
 
#include <inttypes.h>
37
 
 
38
 
#include "CSException.h"
39
 
#include "CSMemory.h"
40
 
#include "CSThread.h"
41
 
#include "CSStrUtil.h"
42
 
#include "CSGlobal.h"
43
 
 
44
 
#ifdef DEBUG
45
 
#undef cs_malloc
46
 
#undef cs_calloc
47
 
#undef cs_realloc
48
 
#undef cs_free
49
 
#undef new
50
 
#endif
51
 
 
52
 
void *cs_malloc(size_t size)
53
 
{
54
 
        void *ptr;
55
 
 
56
 
        if (!(ptr = malloc(size)))
57
 
                CSException::throwOSError(CS_CONTEXT, ENOMEM);
58
 
        return ptr;
59
 
}
60
 
 
61
 
void *cs_calloc(size_t size)
62
 
{
63
 
        void *ptr;
64
 
 
65
 
        if (!(ptr = malloc(size)))
66
 
                CSException::throwOSError(CS_CONTEXT, ENOMEM);
67
 
        memset(ptr, 0, size);
68
 
        return ptr;
69
 
}
70
 
 
71
 
void cs_realloc(void **ptr, size_t size)
72
 
{
73
 
        void *new_ptr;
74
 
        
75
 
        if (!(new_ptr = realloc(*ptr, size)))
76
 
                CSException::throwOSError(CS_CONTEXT, ENOMEM);
77
 
        *ptr = new_ptr;
78
 
}
79
 
 
80
 
void cs_free(void *ptr)
81
 
{
82
 
        free(ptr);
83
 
}
84
 
 
85
 
/*
86
 
 * -----------------------------------------------------------------------
87
 
 * DEBUG MEMORY ALLOCATION AND HEAP CHECKING
88
 
 */
89
 
 
90
 
#ifdef DEBUG
91
 
 
92
 
#define RECORD_MM
93
 
 
94
 
#define ADD_TOTAL_ALLOCS                        4000
95
 
 
96
 
#define SHIFT_RIGHT(ptr, n)                     memmove(((char *) (ptr)) + sizeof(MissingMemoryRec), (ptr), (long) (n) * sizeof(MissingMemoryRec))
97
 
#define SHIFT_LEFT(ptr, n)                      memmove((ptr), ((char *) (ptr)) + sizeof(MissingMemoryRec), (long) (n) * sizeof(MissingMemoryRec))
98
 
 
99
 
typedef struct MissingMemory {
100
 
        void                    *ptr;
101
 
        uint32_t                        id;
102
 
        const char              *func_name;
103
 
        const char              *file_name;
104
 
        uint32_t                        line_nr;
105
 
} MissingMemoryRec, *MissingMemoryPtr;
106
 
 
107
 
static MissingMemoryRec *mm_addresses = NULL;
108
 
static uint32_t                 mm_nr_in_use = 0L;
109
 
static uint32_t                 mm_total_allocated = 0L;
110
 
static uint32_t                 mm_alloc_count = 0;
111
 
static pthread_mutex_t  mm_mutex;
112
 
 
113
 
/* Set this variable to the ID of the memory you want
114
 
 * to track.
115
 
 */
116
 
static uint32_t                 mm_tracking_id = 0;
117
 
 
118
 
static void mm_println(const char *str)
119
 
{
120
 
        printf("%s\n", str);
121
 
}
122
 
 
123
 
static long mm_find_pointer(void *ptr)
124
 
{
125
 
        register long   i, n, guess;
126
 
 
127
 
        i = 0;
128
 
        n = mm_nr_in_use;
129
 
        while (i < n) {
130
 
                guess = (i + n - 1) >> 1;
131
 
                if (ptr == mm_addresses[guess].ptr)
132
 
                        return(guess);
133
 
                if (ptr < mm_addresses[guess].ptr)
134
 
                        n = guess;
135
 
                else
136
 
                        i = guess + 1;
137
 
        }
138
 
        return(-1);
139
 
}
140
 
 
141
 
static long mm_add_pointer(void *ptr)
142
 
{
143
 
        register int    i, n, guess;
144
 
 
145
 
        if (mm_nr_in_use == mm_total_allocated) {
146
 
                /* Not enough space, add more: */
147
 
                MissingMemoryRec *new_addresses;
148
 
 
149
 
                new_addresses = (MissingMemoryRec *) malloc(sizeof(MissingMemoryRec) * (mm_total_allocated + ADD_TOTAL_ALLOCS));
150
 
                if (!new_addresses)
151
 
                        return(-1);
152
 
 
153
 
                if (mm_addresses) {
154
 
                        memcpy(new_addresses, mm_addresses, sizeof(MissingMemoryRec) * mm_total_allocated);
155
 
                        free(mm_addresses);
156
 
                }
157
 
 
158
 
                mm_addresses = new_addresses;
159
 
                mm_total_allocated += ADD_TOTAL_ALLOCS;
160
 
        }
161
 
 
162
 
        i = 0;
163
 
        n = mm_nr_in_use;
164
 
        while (i < n) {
165
 
                guess = (i + n - 1) >> 1;
166
 
                if (ptr < mm_addresses[guess].ptr)
167
 
                        n = guess;
168
 
                else
169
 
                        i = guess + 1;
170
 
        }
171
 
 
172
 
        SHIFT_RIGHT(&mm_addresses[i], mm_nr_in_use - i);
173
 
        mm_nr_in_use++;
174
 
        mm_addresses[i].ptr = ptr;
175
 
        return(i);
176
 
}
177
 
 
178
 
static char *cs_mm_watch_point = 0;
179
 
 
180
 
static long mm_remove_pointer(void *ptr)
181
 
{
182
 
        register int    i, n, guess;
183
 
 
184
 
        if (cs_mm_watch_point == ptr)
185
 
                printf("Hit watch point\n");
186
 
 
187
 
        i = 0;
188
 
        n = mm_nr_in_use;
189
 
        while (i < n) {
190
 
                guess = (i + n - 1) >> 1;
191
 
                if (ptr == mm_addresses[guess].ptr)
192
 
                        goto remove;
193
 
                if (ptr < mm_addresses[guess].ptr)
194
 
                        n = guess;
195
 
                else
196
 
                        i = guess + 1;
197
 
        }
198
 
        return(-1);
199
 
 
200
 
        remove:
201
 
        /* Decrease the number of sets, and shift left: */
202
 
        mm_nr_in_use--;
203
 
        SHIFT_LEFT(&mm_addresses[guess], mm_nr_in_use - guess); 
204
 
        return(guess);
205
 
}
206
 
 
207
 
static void mm_throw_assertion(MissingMemoryPtr mm_ptr, void *p, const char *message)
208
 
{
209
 
        char str[200];
210
 
 
211
 
        if (mm_ptr) {
212
 
                snprintf(str, 200, "MM ERROR: %8p (#%"PRId32") %s:%"PRId32" %s",
213
 
                                           mm_ptr->ptr,
214
 
                                           mm_ptr->id,
215
 
                                           cs_last_name_of_path(mm_ptr->file_name),
216
 
                                           mm_ptr->line_nr,
217
 
                                           message);
218
 
        }
219
 
        else
220
 
                snprintf(str, 200, "MM ERROR: %8p %s", p, message);
221
 
        mm_println(str);
222
 
}
223
 
 
224
 
static uint32_t mm_add_core_ptr(void *ptr, const char *func, const char *file, int line)
225
 
{
226
 
        long    mm;
227
 
        uint32_t        id;
228
 
 
229
 
        mm = mm_add_pointer(ptr);
230
 
        if (mm < 0) {
231
 
                mm_println("MM ERROR: Cannot allocate table big enough!");
232
 
                return 0;
233
 
        }
234
 
 
235
 
        /* Record the pointer: */
236
 
        if (mm_alloc_count == mm_tracking_id) { 
237
 
                /* Enable you to set a breakpoint: */
238
 
                id = mm_alloc_count++; // DEBUG-BREAK-POINT
239
 
        }
240
 
        else {
241
 
                id = mm_alloc_count++;
242
 
        }
243
 
        mm_addresses[mm].ptr = ptr;
244
 
        mm_addresses[mm].id = id;
245
 
        mm_addresses[mm].func_name = func;
246
 
        if (file)
247
 
                mm_addresses[mm].file_name = file;
248
 
        else
249
 
                mm_addresses[mm].file_name = "?";
250
 
        mm_addresses[mm].line_nr = line;
251
 
        return id;
252
 
}
253
 
 
254
 
static void mm_remove_core_ptr(void *ptr)
255
 
{
256
 
        long mm;
257
 
 
258
 
        mm = mm_remove_pointer(ptr);
259
 
        if (mm < 0) {
260
 
                mm_println("MM ERROR: Pointer not allocated");
261
 
                return;
262
 
        }
263
 
}
264
 
 
265
 
static long mm_find_core_ptr(void *ptr)
266
 
{
267
 
        long mm;
268
 
 
269
 
        mm = mm_find_pointer(ptr);
270
 
        if (mm < 0)
271
 
                mm_throw_assertion(NULL, ptr, "Pointer not allocated");
272
 
        return(mm);
273
 
}
274
 
 
275
 
static void mm_replace_core_ptr(long i, void *ptr)
276
 
{
277
 
        MissingMemoryRec        tmp = mm_addresses[i];
278
 
        long                            mm;
279
 
 
280
 
        mm_remove_pointer(mm_addresses[i].ptr);
281
 
        mm = mm_add_pointer(ptr);
282
 
        if (mm < 0) {
283
 
                mm_println("MM ERROR: Cannot allocate table big enough!");
284
 
                return;
285
 
        }
286
 
        mm_addresses[mm] = tmp;
287
 
        mm_addresses[mm].ptr = ptr;
288
 
}
289
 
 
290
 
/*
291
 
 * -----------------------------------------------------------------------
292
 
 * MISSING MEMORY PUBLIC ROUTINES
293
 
 */
294
 
 
295
 
#define MEM_DEBUG_HDR_SIZE              offsetof(MemoryDebugRec, data)
296
 
#define MEM_TRAILER_SIZE                2
297
 
#define MEM_HEADER                              0x01010101
298
 
#define MEM_FREED                               0x03030303
299
 
#define MEM_TRAILER_BYTE                0x02
300
 
#define MEM_FREED_BYTE                  0x03
301
 
 
302
 
typedef struct MemoryDebug {
303
 
        uint32_t                check;
304
 
        uint32_t                md_id;                          /* The memory ID! */
305
 
        uint32_t                size;
306
 
        char            data[200];
307
 
} MemoryDebugRec, *MemoryDebugPtr;
308
 
 
309
 
static size_t mm_check_and_free(MissingMemoryPtr mm_ptr, void *p, bool freeme)
310
 
{
311
 
        unsigned char   *ptr = (unsigned char *) p - MEM_DEBUG_HDR_SIZE;
312
 
        MemoryDebugPtr  debug_ptr = (MemoryDebugPtr) ptr;
313
 
        size_t                  size = debug_ptr->size;
314
 
        long                    a_value;  /* Added to simplfy debugging. */
315
 
 
316
 
        if (!ASSERT(p)) 
317
 
                return(0);
318
 
        if (!ASSERT(((size_t) p & 1L) == 0)) 
319
 
                return(0);
320
 
        a_value = MEM_FREED;
321
 
        if (debug_ptr->check == MEM_FREED) { 
322
 
                mm_println("MM ERROR: Pointer already freed 'debug_ptr->check != MEM_FREED'");
323
 
                return(0);
324
 
        }
325
 
        a_value = MEM_HEADER;
326
 
        if (debug_ptr->check != MEM_HEADER) {
327
 
                mm_println("MM ERROR: Header not valid 'debug_ptr->check != MEM_HEADER'");
328
 
                return(0);
329
 
        }
330
 
        a_value = MEM_TRAILER_BYTE;
331
 
        if (!(*((unsigned char *) ptr + size + MEM_DEBUG_HDR_SIZE) == MEM_TRAILER_BYTE &&
332
 
                        *((unsigned char *) ptr + size + MEM_DEBUG_HDR_SIZE + 1L) == MEM_TRAILER_BYTE)) { 
333
 
                mm_throw_assertion(mm_ptr, p, "Trailer overwritten");
334
 
                return(0);
335
 
        }
336
 
 
337
 
        if (freeme) {
338
 
                debug_ptr->check = MEM_FREED;
339
 
                *((unsigned char *) ptr + size + MEM_DEBUG_HDR_SIZE) = MEM_FREED_BYTE;
340
 
                *((unsigned char *) ptr + size + MEM_DEBUG_HDR_SIZE + 1L) = MEM_FREED_BYTE;
341
 
 
342
 
                memset(((unsigned char *) ptr) + MEM_DEBUG_HDR_SIZE, 0xF5, size);
343
 
                cs_free(ptr);
344
 
        }
345
 
 
346
 
        return size;
347
 
}
348
 
 
349
 
bool cs_mm_scan_core(void)
350
 
{
351
 
        uint32_t mm;
352
 
        bool rtc = true;
353
 
 
354
 
        if (!mm_addresses)
355
 
                return true;
356
 
 
357
 
        pthread_mutex_lock(&mm_mutex);
358
 
 
359
 
        for (mm=0; mm<mm_nr_in_use; mm++)       {
360
 
                if (!mm_check_and_free(&mm_addresses[mm], mm_addresses[mm].ptr, false))
361
 
                        rtc = false;
362
 
        }
363
 
        
364
 
        pthread_mutex_unlock(&mm_mutex);
365
 
        return rtc;
366
 
}
367
 
 
368
 
void cs_mm_memmove(void *block, void *dest, void *source, size_t size)
369
 
{
370
 
        if (block) {
371
 
                MemoryDebugPtr  debug_ptr = (MemoryDebugPtr) ((char *) block - MEM_DEBUG_HDR_SIZE);
372
 
 
373
 
#ifdef RECORD_MM
374
 
                pthread_mutex_lock(&mm_mutex);
375
 
                mm_find_core_ptr(block);
376
 
                pthread_mutex_unlock(&mm_mutex);
377
 
#endif
378
 
                mm_check_and_free(NULL, block, false);
379
 
 
380
 
                if (dest < block || (char *) dest > (char *) block + debug_ptr->size) {
381
 
                        mm_println("MM ERROR: Destination not in block");
382
 
                        return;
383
 
                }
384
 
                if ((char *) dest + size > (char *) block + debug_ptr->size) {
385
 
                        mm_println("MM ERROR: Copy will overwrite memory");
386
 
                        return;
387
 
                }
388
 
        }
389
 
 
390
 
        memmove(dest, source, size);
391
 
}
392
 
 
393
 
void cs_mm_memcpy(void *block, void *dest, void *source, size_t size)
394
 
{
395
 
        if (block) {
396
 
                MemoryDebugPtr  debug_ptr = (MemoryDebugPtr) ((char *) block - MEM_DEBUG_HDR_SIZE);
397
 
 
398
 
#ifdef RECORD_MM
399
 
                pthread_mutex_lock(&mm_mutex);
400
 
                mm_find_core_ptr(block);
401
 
                pthread_mutex_unlock(&mm_mutex);
402
 
#endif
403
 
                mm_check_and_free(NULL, block, false);
404
 
 
405
 
                if (dest < block || (char *) dest > (char *) block + debug_ptr->size)
406
 
                        mm_throw_assertion(NULL, block, "Destination not in block");
407
 
                if ((char *) dest + size > (char *) block + debug_ptr->size)
408
 
                        mm_throw_assertion(NULL, block, "Copy will overwrite memory");
409
 
        }
410
 
 
411
 
        memcpy(dest, source, size);
412
 
}
413
 
 
414
 
void cs_mm_memset(void *block, void *dest, int value, size_t size)
415
 
{
416
 
        if (block) {
417
 
                MemoryDebugPtr  debug_ptr = (MemoryDebugPtr) ((char *) block - MEM_DEBUG_HDR_SIZE);
418
 
 
419
 
#ifdef RECORD_MM
420
 
                pthread_mutex_lock(&mm_mutex);
421
 
                mm_find_core_ptr(block);
422
 
                pthread_mutex_unlock(&mm_mutex);
423
 
#endif
424
 
                mm_check_and_free(NULL, block, false);
425
 
 
426
 
                if (dest < block || (char *) dest > (char *) block + debug_ptr->size)
427
 
                        mm_throw_assertion(NULL, block, "Destination not in block");
428
 
                if ((char *) dest + size > (char *) block + debug_ptr->size)
429
 
                        mm_throw_assertion(NULL, block, "Copy will overwrite memory");
430
 
        }
431
 
 
432
 
        memset(dest, value, size);
433
 
}
434
 
 
435
 
void *cs_mm_malloc(const char *func, const char *file, int line, size_t size)
436
 
{
437
 
        unsigned char *p = (unsigned char *) cs_malloc(size + MEM_DEBUG_HDR_SIZE + MEM_TRAILER_SIZE);
438
 
 
439
 
        if (!p)
440
 
                return NULL;
441
 
 
442
 
        memset(p, 0x55, size + MEM_DEBUG_HDR_SIZE + MEM_TRAILER_SIZE);
443
 
 
444
 
        ((MemoryDebugPtr) p)->check = MEM_HEADER;
445
 
        ((MemoryDebugPtr) p)->md_id = 0;
446
 
        ((MemoryDebugPtr) p)->size = (uint32_t) size;
447
 
        *(p + size + MEM_DEBUG_HDR_SIZE) = MEM_TRAILER_BYTE;
448
 
        *(p + size + MEM_DEBUG_HDR_SIZE + 1L) = MEM_TRAILER_BYTE;
449
 
 
450
 
#ifdef RECORD_MM
451
 
        pthread_mutex_lock(&mm_mutex);
452
 
        ((MemoryDebugPtr) p)->md_id = mm_add_core_ptr(p + MEM_DEBUG_HDR_SIZE, func, file, line);
453
 
        pthread_mutex_unlock(&mm_mutex);
454
 
#endif
455
 
 
456
 
        return p + MEM_DEBUG_HDR_SIZE;
457
 
}
458
 
 
459
 
void *cs_mm_calloc(const char *func, const char *file, int line, size_t size)
460
 
{
461
 
        unsigned char *p = (unsigned char *) cs_calloc(size + MEM_DEBUG_HDR_SIZE + MEM_TRAILER_SIZE);
462
 
 
463
 
        if (!p) 
464
 
                return NULL;
465
 
 
466
 
        ((MemoryDebugPtr) p)->check = MEM_HEADER;
467
 
        ((MemoryDebugPtr) p)->md_id = 0;
468
 
        ((MemoryDebugPtr) p)->size  = (uint32_t) size;
469
 
        *(p + size + MEM_DEBUG_HDR_SIZE) = MEM_TRAILER_BYTE;
470
 
        *(p + size + MEM_DEBUG_HDR_SIZE + 1L) = MEM_TRAILER_BYTE;
471
 
 
472
 
#ifdef RECORD_MM
473
 
        pthread_mutex_lock(&mm_mutex);
474
 
        ((MemoryDebugPtr) p)->md_id = mm_add_core_ptr(p + MEM_DEBUG_HDR_SIZE, func, file, line);
475
 
        pthread_mutex_unlock(&mm_mutex);
476
 
#endif
477
 
 
478
 
        return p + MEM_DEBUG_HDR_SIZE;
479
 
}
480
 
 
481
 
void cs_mm_realloc(const char *func, const char *file, int line, void **ptr, size_t newsize)
482
 
{
483
 
        unsigned char   *oldptr = (unsigned char *) *ptr;
484
 
        size_t                  size;
485
 
        long                    mm;
486
 
        unsigned char   *pnew;
487
 
 
488
 
        if (!oldptr) {
489
 
                *ptr = cs_mm_malloc(func, file, line, newsize);
490
 
                return;
491
 
        }
492
 
 
493
 
#ifdef RECORD_MM
494
 
        // The lock must be held until the realloc has completed otherwise
495
 
        // a scan of the memory may report a bad memory header.
496
 
        pthread_mutex_lock(&mm_mutex);
497
 
        if ((mm = mm_find_core_ptr(oldptr)) < 0) {
498
 
                pthread_mutex_unlock(&mm_mutex);
499
 
                CSException::throwOSError(CS_CONTEXT, ENOMEM);
500
 
        }
501
 
        // pthread_mutex_unlock(&mm_mutex); It will be unlocked below
502
 
#endif
503
 
 
504
 
        oldptr = oldptr - MEM_DEBUG_HDR_SIZE;
505
 
        size = ((MemoryDebugPtr) oldptr)->size;
506
 
 
507
 
        ASSERT(((MemoryDebugPtr) oldptr)->check == MEM_HEADER);
508
 
        ASSERT(*((unsigned char *) oldptr + size + MEM_DEBUG_HDR_SIZE) == MEM_TRAILER_BYTE && 
509
 
                        *((unsigned char *) oldptr + size + MEM_DEBUG_HDR_SIZE + 1L) == MEM_TRAILER_BYTE);
510
 
 
511
 
        /* Grow allways moves! */
512
 
        pnew = (unsigned char *) cs_malloc(newsize + MEM_DEBUG_HDR_SIZE + MEM_TRAILER_SIZE);
513
 
        if (!pnew) {
514
 
#ifdef RECORD_MM
515
 
                pthread_mutex_unlock(&mm_mutex); 
516
 
#endif
517
 
                CSException::throwOSError(CS_CONTEXT, ENOMEM);
518
 
                return;
519
 
        }
520
 
 
521
 
        if (newsize > size) {
522
 
                memcpy(((MemoryDebugPtr) pnew)->data, ((MemoryDebugPtr) oldptr)->data, size);
523
 
                memset(((MemoryDebugPtr) pnew)->data + size, 0x55, newsize - size);
524
 
        }
525
 
        else
526
 
                memcpy(((MemoryDebugPtr) pnew)->data, ((MemoryDebugPtr) oldptr)->data, newsize);
527
 
        memset(oldptr, 0x55, size + MEM_DEBUG_HDR_SIZE + MEM_TRAILER_SIZE);
528
 
 
529
 
#ifdef RECORD_MM
530
 
        // pthread_mutex_lock(&mm_mutex); It was locked above
531
 
        if ((mm = mm_find_core_ptr(oldptr + MEM_DEBUG_HDR_SIZE)) < 0) {
532
 
                pthread_mutex_unlock(&mm_mutex);
533
 
                CSException::throwOSError(CS_CONTEXT, ENOMEM);
534
 
                return;
535
 
        }
536
 
        mm_replace_core_ptr(mm, pnew + MEM_DEBUG_HDR_SIZE);
537
 
        pthread_mutex_unlock(&mm_mutex);
538
 
#endif
539
 
 
540
 
        cs_free(oldptr);
541
 
 
542
 
        ((MemoryDebugPtr) pnew)->check = MEM_HEADER;
543
 
        ((MemoryDebugPtr) pnew)->size = (uint32_t) newsize;
544
 
        *(pnew + newsize + MEM_DEBUG_HDR_SIZE) = MEM_TRAILER_BYTE;
545
 
        *(pnew + newsize + MEM_DEBUG_HDR_SIZE + 1L)     = MEM_TRAILER_BYTE;
546
 
 
547
 
        *ptr = pnew + MEM_DEBUG_HDR_SIZE;
548
 
}
549
 
 
550
 
void cs_mm_free(void *ptr)
551
 
{
552
 
        bool my_pointer = false;
553
 
 
554
 
#ifdef RECORD_MM
555
 
        pthread_mutex_lock(&mm_mutex);
556
 
        if (mm_find_pointer(ptr) >= 0) {
557
 
                my_pointer = true;
558
 
                mm_remove_core_ptr(ptr);
559
 
        }
560
 
        pthread_mutex_unlock(&mm_mutex);
561
 
#endif
562
 
        if (my_pointer)
563
 
                mm_check_and_free(NULL, ptr, true);
564
 
        else
565
 
                free(ptr);
566
 
}
567
 
 
568
 
void cs_mm_pfree(void **ptr)
569
 
{
570
 
        if (*ptr) {
571
 
                void *p = *ptr;
572
 
 
573
 
                *ptr = NULL;
574
 
                cs_mm_free(p);
575
 
        }
576
 
}
577
 
 
578
 
size_t cs_mm_malloc_size(void *ptr)
579
 
{
580
 
        size_t size = 0;
581
 
 
582
 
#ifdef RECORD_MM
583
 
        pthread_mutex_lock(&mm_mutex);
584
 
        mm_find_core_ptr(ptr);
585
 
        pthread_mutex_unlock(&mm_mutex);
586
 
#endif
587
 
        size = mm_check_and_free(NULL, ptr, false);
588
 
        return size;
589
 
}
590
 
 
591
 
void cs_mm_print_track(const char *func, const char *file, uint32_t line, void *p, bool inc, uint32_t ref_cnt, int track_me)
592
 
{
593
 
        unsigned char   *ptr = (unsigned char *) p - MEM_DEBUG_HDR_SIZE;
594
 
        MemoryDebugPtr  debug_ptr = (MemoryDebugPtr) ptr;
595
 
        CSThread                *self = CSThread::getSelf();
596
 
        char                    buffer[300];
597
 
        int                             cnt = 0;
598
 
 
599
 
        if (!track_me && !mm_tracking_id)
600
 
                return;
601
 
 
602
 
        if (func) {
603
 
                cs_format_context(300, buffer, func, file, line);
604
 
                fprintf(stderr, "TRACKING (%"PRIu32"): %s %2"PRIu32" %s", debug_ptr->md_id, inc ? "INC" : "DEC", ref_cnt, buffer);
605
 
        }
606
 
        else
607
 
                fprintf(stderr, "TRACKING (%"PRIu32"): %s %2"PRIu32"", debug_ptr->md_id, inc ? "INC" : "DEC", ref_cnt);
608
 
 
609
 
        for (int i = self->callTop-1; i>=0 && cnt < 4; i--) {
610
 
                cs_format_context(300, buffer, self->callStack[i].cs_func, self->callStack[i].cs_file, self->callStack[i].cs_line);
611
 
                fprintf(stderr," %s", buffer);
612
 
                cnt++;
613
 
        }
614
 
        fprintf(stderr,"\n");
615
 
}
616
 
 
617
 
void cs_mm_track_memory(const char *func, const char *file, uint32_t line, void *p, bool inc, uint32_t ref_cnt, int track_me)
618
 
{
619
 
        unsigned char   *ptr = (unsigned char *) p - MEM_DEBUG_HDR_SIZE;
620
 
        MemoryDebugPtr  debug_ptr = (MemoryDebugPtr) ptr;
621
 
 
622
 
        if (track_me || (mm_tracking_id && debug_ptr->md_id == mm_tracking_id))
623
 
                cs_mm_print_track(func, file, line, p, inc, ref_cnt, track_me);
624
 
}
625
 
 
626
 
#endif
627
 
 
628
 
/*
629
 
 * -----------------------------------------------------------------------
630
 
 * INIT/EXIT MEMORY
631
 
 */
632
 
 
633
 
bool cs_init_memory(void)
634
 
{
635
 
#ifdef DEBUG
636
 
        pthread_mutex_init(&mm_mutex, NULL);
637
 
        mm_addresses = (MissingMemoryRec *) malloc(sizeof(MissingMemoryRec) * ADD_TOTAL_ALLOCS);
638
 
        if (!mm_addresses) {
639
 
                mm_println("MM ERROR: Insuffient memory to allocate MM table");
640
 
                pthread_mutex_destroy(&mm_mutex);
641
 
                return false;
642
 
        }
643
 
 
644
 
        memset(mm_addresses, 0, sizeof(MissingMemoryRec) * ADD_TOTAL_ALLOCS);
645
 
        mm_total_allocated = ADD_TOTAL_ALLOCS;
646
 
        mm_nr_in_use = 0L;
647
 
        mm_alloc_count = 0L;
648
 
#endif
649
 
        return true;
650
 
}
651
 
 
652
 
void cs_exit_memory(void)
653
 
{
654
 
#ifdef DEBUG
655
 
        uint32_t mm;
656
 
 
657
 
        if (!mm_addresses)
658
 
                return;
659
 
 
660
 
        pthread_mutex_lock(&mm_mutex);
661
 
        for (mm=0; mm<mm_nr_in_use; mm++)
662
 
                mm_throw_assertion(&mm_addresses[mm], mm_addresses[mm].ptr, "Not freed");
663
 
        free(mm_addresses);
664
 
        mm_addresses = NULL;
665
 
        mm_nr_in_use = 0L;
666
 
        mm_total_allocated = 0L;
667
 
        mm_alloc_count = 0L;
668
 
        pthread_mutex_unlock(&mm_mutex);
669
 
 
670
 
        pthread_mutex_destroy(&mm_mutex);
671
 
#endif
672
 
}
673
 
 
674
 
#ifdef DEBUG
675
 
uint32_t cs_mm_get_check_point()
676
 
{
677
 
        return mm_alloc_count;
678
 
}
679
 
 
680
 
// Reports any memory allocated after the check_point
681
 
// but has not been freed.
682
 
void cs_mm_assert_check_point(uint32_t check_point)
683
 
{
684
 
        uint32_t mm;
685
 
 
686
 
        if (!mm_addresses)
687
 
                return;
688
 
 
689
 
        pthread_mutex_lock(&mm_mutex);
690
 
        for (mm=0; mm<mm_nr_in_use; mm++) {
691
 
                if (mm_addresses[mm].id >= check_point)
692
 
                        mm_throw_assertion(&mm_addresses[mm], mm_addresses[mm].ptr, "Not freed");
693
 
        }
694
 
 
695
 
        pthread_mutex_unlock(&mm_mutex);
696
 
 
697
 
}
698
 
#endif