~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/innobase/ut/ut0mem.c

  • Committer: Lee
  • Date: 2009-01-01 03:07:33 UTC
  • mto: (758.1.3 devel)
  • mto: This revision was merged to the branch mainline in revision 759.
  • Revision ID: lbieber@lbieber-desktop-20090101030733-fb411b55f07vij8q
more header file cleanup

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*****************************************************************************
2
 
 
3
 
Copyright (C) 1994, 2009, Innobase Oy. All Rights Reserved.
4
 
 
5
 
This program is free software; you can redistribute it and/or modify it under
6
 
the terms of the GNU General Public License as published by the Free Software
7
 
Foundation; version 2 of the License.
8
 
 
9
 
This program is distributed in the hope that it will be useful, but WITHOUT
10
 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
 
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
 
 
13
 
You should have received a copy of the GNU General Public License along with
14
 
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
15
 
St, Fifth Floor, Boston, MA 02110-1301 USA
16
 
 
17
 
*****************************************************************************/
18
 
 
19
 
/********************************************************************//**
20
 
@file ut/ut0mem.c
 
1
/************************************************************************
21
2
Memory primitives
22
3
 
 
4
(c) 1994, 1995 Innobase Oy
 
5
 
23
6
Created 5/11/1994 Heikki Tuuri
24
7
*************************************************************************/
25
8
 
29
12
#include "ut0mem.ic"
30
13
#endif
31
14
 
32
 
#ifndef UNIV_HOTBACKUP
33
 
# include "os0thread.h"
34
 
# include "srv0srv.h"
35
 
 
36
 
#include <stdlib.h>
37
 
#include <errno.h>
38
 
 
39
 
/** This struct is placed first in every allocated memory block */
 
15
#include "mem0mem.h"
 
16
#include "os0sync.h"
 
17
#include "os0thread.h"
 
18
 
 
19
/* This struct is placed first in every allocated memory block */
40
20
typedef struct ut_mem_block_struct ut_mem_block_t;
41
21
 
42
 
/** The total amount of memory currently allocated from the operating
43
 
system with os_mem_alloc_large() or malloc().  Does not count malloc()
44
 
if srv_use_sys_malloc is set.  Protected by ut_list_mutex. */
45
 
UNIV_INTERN ulint               ut_total_allocated_memory       = 0;
46
 
 
47
 
/** Mutex protecting ut_total_allocated_memory and ut_mem_block_list */
48
 
UNIV_INTERN os_fast_mutex_t     ut_list_mutex;
49
 
 
50
 
/** Dynamically allocated memory block */
 
22
/* The total amount of memory currently allocated from the OS with malloc */
 
23
UNIV_INTERN ulint       ut_total_allocated_memory       = 0;
 
24
 
51
25
struct ut_mem_block_struct{
52
26
        UT_LIST_NODE_T(ut_mem_block_t) mem_block_list;
53
 
                        /*!< mem block list node */
54
 
        ulint   size;   /*!< size of allocated memory */
55
 
        ulint   magic_n;/*!< magic number (UT_MEM_MAGIC_N) */
 
27
                        /* mem block list node */
 
28
        ulint   size;   /* size of allocated memory */
 
29
        ulint   magic_n;
56
30
};
57
31
 
58
 
/** The value of ut_mem_block_struct::magic_n.  Used in detecting
59
 
memory corruption. */
60
32
#define UT_MEM_MAGIC_N  1601650166
61
33
 
62
 
/** List of all memory blocks allocated from the operating system
63
 
with malloc.  Protected by ut_list_mutex. */
 
34
/* List of all memory blocks allocated from the operating system
 
35
with malloc */
64
36
static UT_LIST_BASE_NODE_T(ut_mem_block_t)   ut_mem_block_list;
65
37
 
66
 
/** Flag: has ut_mem_block_list been initialized? */
 
38
static os_fast_mutex_t ut_list_mutex;   /* this protects the list */
 
39
 
67
40
static ibool  ut_mem_block_list_inited = FALSE;
68
41
 
69
 
/** A dummy pointer for generating a null pointer exception in
70
 
ut_malloc_low() */
71
42
static ulint*   ut_mem_null_ptr = NULL;
72
43
 
73
 
/**********************************************************************//**
 
44
/**************************************************************************
74
45
Initializes the mem block list at database startup. */
75
 
UNIV_INTERN
 
46
static
76
47
void
77
 
ut_mem_init(void)
78
 
/*=============*/
 
48
ut_mem_block_list_init(void)
 
49
/*========================*/
79
50
{
80
 
        ut_a(!ut_mem_block_list_inited);
81
51
        os_fast_mutex_init(&ut_list_mutex);
82
52
        UT_LIST_INIT(ut_mem_block_list);
83
53
        ut_mem_block_list_inited = TRUE;
84
54
}
85
 
#endif /* !UNIV_HOTBACKUP */
86
55
 
87
 
/**********************************************************************//**
 
56
/**************************************************************************
88
57
Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is
89
 
defined and set_to_zero is TRUE.
90
 
@return own: allocated memory */
 
58
defined and set_to_zero is TRUE. */
91
59
UNIV_INTERN
92
60
void*
93
61
ut_malloc_low(
94
62
/*==========*/
95
 
        ulint   n,              /*!< in: number of bytes to allocate */
96
 
        ibool   set_to_zero,    /*!< in: TRUE if allocated memory should be
 
63
                                /* out, own: allocated memory */
 
64
        ulint   n,              /* in: number of bytes to allocate */
 
65
        ibool   set_to_zero,    /* in: TRUE if allocated memory should be
97
66
                                set to zero if UNIV_SET_MEM_TO_ZERO is
98
67
                                defined */
99
 
        ibool   assert_on_error)/*!< in: if TRUE, we crash mysqld if the
 
68
        ibool   assert_on_error)/* in: if TRUE, we crash mysqld if the
100
69
                                memory cannot be allocated */
101
70
{
102
 
#ifndef UNIV_HOTBACKUP
103
 
        ulint   retry_count;
 
71
        ulint   retry_count     = 0;
104
72
        void*   ret;
105
73
 
106
 
        if (UNIV_LIKELY(srv_use_sys_malloc)) {
107
 
                ret = malloc(n);
108
 
                ut_a(ret || !assert_on_error);
109
 
 
110
 
#ifdef UNIV_SET_MEM_TO_ZERO
111
 
                if (set_to_zero) {
112
 
                        memset(ret, '\0', n);
113
 
                        UNIV_MEM_ALLOC(ret, n);
114
 
                }
115
 
#endif
116
 
                return(ret);
117
 
        }
118
 
 
119
74
        ut_ad((sizeof(ut_mem_block_t) % 8) == 0); /* check alignment ok */
120
 
        ut_a(ut_mem_block_list_inited);
121
75
 
122
 
        retry_count = 0;
 
76
        if (!ut_mem_block_list_inited) {
 
77
                ut_mem_block_list_init();
 
78
        }
123
79
retry:
124
80
        os_fast_mutex_lock(&ut_list_mutex);
125
81
 
180
136
 
181
137
                /* Make an intentional seg fault so that we get a stack
182
138
                trace */
 
139
                /* Intentional segfault on NetWare causes an abend. Avoid this
 
140
                by graceful exit handling in ut_a(). */
 
141
#if (!defined __NETWARE__)
183
142
                if (assert_on_error) {
184
143
                        ut_print_timestamp(stderr);
185
144
 
192
151
                } else {
193
152
                        return(NULL);
194
153
                }
 
154
#else
 
155
                ut_a(0);
 
156
#endif
195
157
        }
196
158
 
197
159
        if (set_to_zero) {
212
174
        os_fast_mutex_unlock(&ut_list_mutex);
213
175
 
214
176
        return((void*)((byte*)ret + sizeof(ut_mem_block_t)));
215
 
#else /* !UNIV_HOTBACKUP */
216
 
        void*   ret = malloc(n);
217
 
        ut_a(ret || !assert_on_error);
218
 
 
219
 
# ifdef UNIV_SET_MEM_TO_ZERO
220
 
        if (set_to_zero) {
221
 
                memset(ret, '\0', n);
222
 
        }
223
 
# endif
224
 
        return(ret);
225
 
#endif /* !UNIV_HOTBACKUP */
226
177
}
227
178
 
228
 
/**********************************************************************//**
 
179
/**************************************************************************
229
180
Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is
230
 
defined.
231
 
@return own: allocated memory */
232
 
extern "C"
 
181
defined. */
233
182
UNIV_INTERN
234
183
void*
235
184
ut_malloc(
236
185
/*======*/
237
 
        ulint   n)      /*!< in: number of bytes to allocate */
 
186
                        /* out, own: allocated memory */
 
187
        ulint   n)      /* in: number of bytes to allocate */
238
188
{
239
 
#ifndef UNIV_HOTBACKUP
240
189
        return(ut_malloc_low(n, TRUE, TRUE));
241
 
#else /* !UNIV_HOTBACKUP */
242
 
        return(malloc(n));
243
 
#endif /* !UNIV_HOTBACKUP */
244
190
}
245
191
 
246
 
#ifndef UNIV_HOTBACKUP
247
 
/**********************************************************************//**
 
192
/**************************************************************************
248
193
Tests if malloc of n bytes would succeed. ut_malloc() asserts if memory runs
249
194
out. It cannot be used if we want to return an error message. Prints to
250
 
stderr a message if fails.
251
 
@return TRUE if succeeded */
 
195
stderr a message if fails. */
252
196
UNIV_INTERN
253
197
ibool
254
198
ut_test_malloc(
255
199
/*===========*/
256
 
        ulint   n)      /*!< in: try to allocate this many bytes */
 
200
                        /* out: TRUE if succeeded */
 
201
        ulint   n)      /* in: try to allocate this many bytes */
257
202
{
258
203
        void*   ret;
259
204
 
283
228
 
284
229
        return(TRUE);
285
230
}
286
 
#endif /* !UNIV_HOTBACKUP */
287
231
 
288
 
/**********************************************************************//**
289
 
Frees a memory block allocated with ut_malloc. Freeing a NULL pointer is
290
 
a nop. */
291
 
extern "C"
 
232
/**************************************************************************
 
233
Frees a memory block allocated with ut_malloc. */
292
234
UNIV_INTERN
293
235
void
294
236
ut_free(
295
237
/*====*/
296
 
        void* ptr)  /*!< in, own: memory block, can be NULL */
 
238
        void* ptr)  /* in, own: memory block */
297
239
{
298
 
#ifndef UNIV_HOTBACKUP
299
240
        ut_mem_block_t* block;
300
241
 
301
 
        if (ptr == NULL) {
302
 
                return;
303
 
        } else if (UNIV_LIKELY(srv_use_sys_malloc)) {
304
 
                free(ptr);
305
 
                return;
306
 
        }
307
 
 
308
242
        block = (ut_mem_block_t*)((byte*)ptr - sizeof(ut_mem_block_t));
309
243
 
310
244
        os_fast_mutex_lock(&ut_list_mutex);
318
252
        free(block);
319
253
 
320
254
        os_fast_mutex_unlock(&ut_list_mutex);
321
 
#else /* !UNIV_HOTBACKUP */
322
 
        free(ptr);
323
 
#endif /* !UNIV_HOTBACKUP */
324
255
}
325
256
 
326
 
#ifndef UNIV_HOTBACKUP
327
 
/**********************************************************************//**
 
257
/**************************************************************************
328
258
Implements realloc. This is needed by /pars/lexyy.c. Otherwise, you should not
329
259
use this function because the allocation functions in mem0mem.h are the
330
260
recommended ones in InnoDB.
333
263
 
334
264
       realloc()  changes the size of the memory block pointed to
335
265
       by ptr to size bytes.  The contents will be  unchanged  to
336
 
       the minimum of the old and new sizes; newly allocated mem-
 
266
       the minimum of the old and new sizes; newly allocated mem�
337
267
       ory will be uninitialized.  If ptr is NULL,  the  call  is
338
268
       equivalent  to malloc(size); if size is equal to zero, the
339
269
       call is equivalent to free(ptr).  Unless ptr is  NULL,  it
347
277
       size  was equal to 0, either NULL or a pointer suitable to
348
278
       be passed to free() is returned.  If realloc()  fails  the
349
279
       original  block  is  left  untouched  - it is not freed or
350
 
       moved.
351
 
@return own: pointer to new mem block or NULL */
352
 
extern "C"
 
280
       moved. */
353
281
UNIV_INTERN
354
282
void*
355
283
ut_realloc(
356
284
/*=======*/
357
 
        void*   ptr,    /*!< in: pointer to old block or NULL */
358
 
        ulint   size)   /*!< in: desired size */
 
285
                        /* out, own: pointer to new mem block or NULL */
 
286
        void*   ptr,    /* in: pointer to old block or NULL */
 
287
        ulint   size)   /* in: desired size */
359
288
{
360
289
        ut_mem_block_t* block;
361
290
        ulint           old_size;
362
291
        ulint           min_size;
363
292
        void*           new_ptr;
364
293
 
365
 
        if (UNIV_LIKELY(srv_use_sys_malloc)) {
366
 
                return(realloc(ptr, size));
367
 
        }
368
 
 
369
294
        if (ptr == NULL) {
370
295
 
371
296
                return(ut_malloc(size));
404
329
        return(new_ptr);
405
330
}
406
331
 
407
 
/**********************************************************************//**
 
332
/**************************************************************************
408
333
Frees in shutdown all allocated memory not freed yet. */
409
334
UNIV_INTERN
410
335
void
413
338
{
414
339
        ut_mem_block_t* block;
415
340
 
416
 
        ut_a(ut_mem_block_list_inited);
417
 
        ut_mem_block_list_inited = FALSE;
418
341
        os_fast_mutex_free(&ut_list_mutex);
419
342
 
420
343
        while ((block = UT_LIST_GET_FIRST(ut_mem_block_list))) {
434
357
                        " total allocated memory is %lu\n",
435
358
                        (ulong) ut_total_allocated_memory);
436
359
        }
437
 
 
438
 
        ut_mem_block_list_inited = FALSE;
439
360
}
440
 
#endif /* !UNIV_HOTBACKUP */
441
361
 
442
 
/**********************************************************************//**
 
362
/**************************************************************************
443
363
Copies up to size - 1 characters from the NUL-terminated string src to
444
364
dst, NUL-terminating the result. Returns strlen(src), so truncation
445
 
occurred if the return value >= size.
446
 
@return strlen(src) */
 
365
occurred if the return value >= size. */
447
366
UNIV_INTERN
448
367
ulint
449
368
ut_strlcpy(
450
369
/*=======*/
451
 
        char*           dst,    /*!< in: destination buffer */
452
 
        const char*     src,    /*!< in: source buffer */
453
 
        ulint           size)   /*!< in: size of destination buffer */
 
370
                                /* out: strlen(src) */
 
371
        char*           dst,    /* in: destination buffer */
 
372
        const char*     src,    /* in: source buffer */
 
373
        ulint           size)   /* in: size of destination buffer */
454
374
{
455
375
        ulint   src_size = strlen(src);
456
376
 
464
384
        return(src_size);
465
385
}
466
386
 
467
 
/**********************************************************************//**
 
387
/**************************************************************************
468
388
Like ut_strlcpy, but if src doesn't fit in dst completely, copies the last
469
 
(size - 1) bytes of src, not the first.
470
 
@return strlen(src) */
 
389
(size - 1) bytes of src, not the first. */
471
390
UNIV_INTERN
472
391
ulint
473
392
ut_strlcpy_rev(
474
393
/*===========*/
475
 
        char*           dst,    /*!< in: destination buffer */
476
 
        const char*     src,    /*!< in: source buffer */
477
 
        ulint           size)   /*!< in: size of destination buffer */
 
394
                                /* out: strlen(src) */
 
395
        char*           dst,    /* in: destination buffer */
 
396
        const char*     src,    /* in: source buffer */
 
397
        ulint           size)   /* in: size of destination buffer */
478
398
{
479
399
        ulint   src_size = strlen(src);
480
400
 
487
407
        return(src_size);
488
408
}
489
409
 
490
 
/**********************************************************************//**
 
410
/**************************************************************************
491
411
Make a quoted copy of a NUL-terminated string.  Leading and trailing
492
412
quotes will not be included; only embedded quotes will be escaped.
493
 
See also ut_strlenq() and ut_memcpyq().
494
 
@return pointer to end of dest */
 
413
See also ut_strlenq() and ut_memcpyq(). */
495
414
UNIV_INTERN
496
415
char*
497
416
ut_strcpyq(
498
417
/*=======*/
499
 
        char*           dest,   /*!< in: output buffer */
500
 
        char            q,      /*!< in: the quote character */
501
 
        const char*     src)    /*!< in: null-terminated string */
 
418
                                /* out: pointer to end of dest */
 
419
        char*           dest,   /* in: output buffer */
 
420
        char            q,      /* in: the quote character */
 
421
        const char*     src)    /* in: null-terminated string */
502
422
{
503
423
        while (*src) {
504
424
                if ((*dest++ = *src++) == q) {
509
429
        return(dest);
510
430
}
511
431
 
512
 
/**********************************************************************//**
 
432
/**************************************************************************
513
433
Make a quoted copy of a fixed-length string.  Leading and trailing
514
434
quotes will not be included; only embedded quotes will be escaped.
515
 
See also ut_strlenq() and ut_strcpyq().
516
 
@return pointer to end of dest */
 
435
See also ut_strlenq() and ut_strcpyq(). */
517
436
UNIV_INTERN
518
437
char*
519
438
ut_memcpyq(
520
439
/*=======*/
521
 
        char*           dest,   /*!< in: output buffer */
522
 
        char            q,      /*!< in: the quote character */
523
 
        const char*     src,    /*!< in: string to be quoted */
524
 
        ulint           len)    /*!< in: length of src */
 
440
                                /* out: pointer to end of dest */
 
441
        char*           dest,   /* in: output buffer */
 
442
        char            q,      /* in: the quote character */
 
443
        const char*     src,    /* in: string to be quoted */
 
444
        ulint           len)    /* in: length of src */
525
445
{
526
446
        const char*     srcend = src + len;
527
447
 
534
454
        return(dest);
535
455
}
536
456
 
537
 
#ifndef UNIV_HOTBACKUP
538
 
/**********************************************************************//**
 
457
/**************************************************************************
539
458
Return the number of times s2 occurs in s1. Overlapping instances of s2
540
 
are only counted once.
541
 
@return the number of times s2 occurs in s1 */
 
459
are only counted once. */
542
460
UNIV_INTERN
543
461
ulint
544
462
ut_strcount(
545
463
/*========*/
546
 
        const char*     s1,     /*!< in: string to search in */
547
 
        const char*     s2)     /*!< in: string to search for */
 
464
                                /* out: the number of times s2 occurs in s1 */
 
465
        const char*     s1,     /* in: string to search in */
 
466
        const char*     s2)     /* in: string to search for */
548
467
{
549
468
        ulint   count = 0;
550
469
        ulint   len = strlen(s2);
569
488
        return(count);
570
489
}
571
490
 
572
 
/**********************************************************************//**
 
491
/**************************************************************************
573
492
Replace every occurrence of s1 in str with s2. Overlapping instances of s1
574
 
are only replaced once.
575
 
@return own: modified string, must be freed with mem_free() */
 
493
are only replaced once. */
576
494
UNIV_INTERN
577
495
char*
578
496
ut_strreplace(
579
497
/*==========*/
580
 
        const char*     str,    /*!< in: string to operate on */
581
 
        const char*     s1,     /*!< in: string to replace */
582
 
        const char*     s2)     /*!< in: string to replace s1 with */
 
498
                                /* out, own: modified string, must be
 
499
                                freed with mem_free() */
 
500
        const char*     str,    /* in: string to operate on */
 
501
        const char*     s1,     /* in: string to replace */
 
502
        const char*     s2)     /* in: string to replace s1 with */
583
503
{
584
504
        char*           new_str;
585
505
        char*           ptr;
598
518
                count = ut_strcount(str, s1);
599
519
        }
600
520
 
601
 
        new_str = static_cast<char *>(mem_alloc(str_len + count * len_delta + 1));
 
521
        new_str = mem_alloc(str_len + count * len_delta + 1);
602
522
        ptr = new_str;
603
523
 
604
524
        while (str) {
706
626
}
707
627
 
708
628
#endif /* UNIV_COMPILE_TEST_FUNCS */
709
 
#endif /* !UNIV_HOTBACKUP */