~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/my_alloc.c

  • Committer: Monty Taylor
  • Date: 2008-08-01 22:33:44 UTC
  • mto: (236.1.42 codestyle)
  • mto: This revision was merged to the branch mainline in revision 261.
  • Revision ID: monty@inaugust.com-20080801223344-vzhlflfmtijp1imv
First pass at gettexizing the error messages.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 
16
16
/* Routines to handle mallocing of results which will be freed the same time */
17
17
 
18
 
#include "drizzled/internal/mysys_priv.h"
19
 
#include "drizzled/internal/m_string.h"
20
 
 
21
 
#include <algorithm>
22
 
 
23
 
using namespace std;
24
 
 
25
 
namespace drizzled
26
 
{
27
 
 
28
 
static const unsigned int MAX_BLOCK_TO_DROP= 4096;
29
 
static const unsigned int MAX_BLOCK_USAGE_BEFORE_DROP= 10;
 
18
#include <mystrings/m_string.h>
 
19
#include <my_sys.h>
 
20
#undef EXTRA_DEBUG
 
21
#define EXTRA_DEBUG
 
22
 
30
23
 
31
24
/*
32
25
  Initialize memory root
33
26
 
34
27
  SYNOPSIS
35
 
    memory::init_alloc_root()
 
28
    init_alloc_root()
36
29
      mem_root       - memory root to initialize
37
30
      block_size     - size of chunks (blocks) used for memory allocation
38
31
                       (It is external size of chunk i.e. it should include
39
32
                        memory required for internal structures, thus it
40
 
                        should be no less than memory::ROOT_MIN_BLOCK_SIZE)
 
33
                        should be no less than ALLOC_ROOT_MIN_BLOCK_SIZE)
 
34
      pre_alloc_size - if non-0, then size of block that should be
 
35
                       pre-allocated during memory root initialization.
41
36
 
42
37
  DESCRIPTION
43
38
    This function prepares memory root for further use, sets initial size of
47
42
    reported as error in first alloc_root() on this memory root.
48
43
*/
49
44
 
50
 
void memory::init_alloc_root(memory::Root *mem_root, size_t block_size)
 
45
void init_alloc_root(MEM_ROOT *mem_root, size_t block_size,
 
46
                     size_t pre_alloc_size __attribute__((unused)))
51
47
{
52
48
  mem_root->free= mem_root->used= mem_root->pre_alloc= 0;
53
49
  mem_root->min_malloc= 32;
54
 
  mem_root->block_size= block_size - memory::ROOT_MIN_BLOCK_SIZE;
 
50
  mem_root->block_size= block_size - ALLOC_ROOT_MIN_BLOCK_SIZE;
55
51
  mem_root->error_handler= 0;
56
52
  mem_root->block_num= 4;                       /* We shift this with >>2 */
57
53
  mem_root->first_block_usage= 0;
58
54
 
 
55
#if !(defined(HAVE_purify) && defined(EXTRA_DEBUG))
 
56
  if (pre_alloc_size)
 
57
  {
 
58
    if ((mem_root->free= mem_root->pre_alloc=
 
59
         (USED_MEM*) my_malloc(pre_alloc_size+ ALIGN_SIZE(sizeof(USED_MEM)),
 
60
                               MYF(0))))
 
61
    {
 
62
      mem_root->free->size= pre_alloc_size+ALIGN_SIZE(sizeof(USED_MEM));
 
63
      mem_root->free->left= pre_alloc_size;
 
64
      mem_root->free->next= 0;
 
65
    }
 
66
  }
 
67
#endif
59
68
  return;
60
69
}
61
70
 
77
86
    before allocation.
78
87
*/
79
88
 
80
 
void memory::reset_root_defaults(memory::Root *mem_root, size_t block_size,
81
 
                                 size_t pre_alloc_size)
 
89
void reset_root_defaults(MEM_ROOT *mem_root, size_t block_size,
 
90
                         size_t pre_alloc_size __attribute__((unused)))
82
91
{
83
92
  assert(alloc_root_inited(mem_root));
84
93
 
85
 
  mem_root->block_size= block_size - memory::ROOT_MIN_BLOCK_SIZE;
 
94
  mem_root->block_size= block_size - ALLOC_ROOT_MIN_BLOCK_SIZE;
 
95
#if !(defined(HAVE_purify) && defined(EXTRA_DEBUG))
86
96
  if (pre_alloc_size)
87
97
  {
88
 
    size_t size= pre_alloc_size + ALIGN_SIZE(sizeof(memory::internal::UsedMemory));
 
98
    size_t size= pre_alloc_size + ALIGN_SIZE(sizeof(USED_MEM));
89
99
    if (!mem_root->pre_alloc || mem_root->pre_alloc->size != size)
90
100
    {
91
 
      memory::internal::UsedMemory *mem, **prev= &mem_root->free;
 
101
      USED_MEM *mem, **prev= &mem_root->free;
92
102
      /*
93
103
        Free unused blocks, so that consequent calls
94
104
        to reset_root_defaults won't eat away memory.
102
112
          mem_root->pre_alloc= mem;
103
113
          return;
104
114
        }
105
 
        if (mem->left + ALIGN_SIZE(sizeof(memory::internal::UsedMemory)) == mem->size)
 
115
        if (mem->left + ALIGN_SIZE(sizeof(USED_MEM)) == mem->size)
106
116
        {
107
117
          /* remove block from the list and free it */
108
118
          *prev= mem->next;
109
 
          free(mem);
 
119
          my_free(mem, MYF(0));
110
120
        }
111
121
        else
112
122
          prev= &mem->next;
113
123
      }
114
124
      /* Allocate new prealloc block and add it to the end of free list */
115
 
      if ((mem= static_cast<memory::internal::UsedMemory *>(malloc(size))))
 
125
      if ((mem= (USED_MEM *) my_malloc(size, MYF(0))))
116
126
      {
117
 
        mem->size= size;
 
127
        mem->size= size; 
118
128
        mem->left= pre_alloc_size;
119
129
        mem->next= *prev;
120
 
        *prev= mem_root->pre_alloc= mem;
 
130
        *prev= mem_root->pre_alloc= mem; 
121
131
      }
122
132
      else
123
133
      {
126
136
    }
127
137
  }
128
138
  else
129
 
  {
 
139
#endif
130
140
    mem_root->pre_alloc= 0;
131
 
  }
132
141
}
133
142
 
134
143
 
135
 
void *memory::alloc_root(memory::Root *mem_root, size_t length)
 
144
void *alloc_root(MEM_ROOT *mem_root, size_t length)
136
145
{
 
146
#if defined(HAVE_purify) && defined(EXTRA_DEBUG)
 
147
  register USED_MEM *next;
 
148
 
 
149
  assert(alloc_root_inited(mem_root));
 
150
 
 
151
  length+=ALIGN_SIZE(sizeof(USED_MEM));
 
152
  if (!(next = (USED_MEM*) my_malloc(length,MYF(MY_WME | ME_FATALERROR))))
 
153
  {
 
154
    if (mem_root->error_handler)
 
155
      (*mem_root->error_handler)();
 
156
    return((uchar*) 0);                 /* purecov: inspected */
 
157
  }
 
158
  next->next= mem_root->used;
 
159
  next->size= length;
 
160
  mem_root->used= next;
 
161
  return((uchar*) (((char*) next)+ALIGN_SIZE(sizeof(USED_MEM))));
 
162
#else
137
163
  size_t get_size, block_size;
138
 
  unsigned char* point;
139
 
  memory::internal::UsedMemory *next= NULL;
140
 
  memory::internal::UsedMemory **prev;
 
164
  uchar* point;
 
165
  register USED_MEM *next= 0;
 
166
  register USED_MEM **prev;
141
167
  assert(alloc_root_inited(mem_root));
142
168
 
143
169
  length= ALIGN_SIZE(length);
144
170
  if ((*(prev= &mem_root->free)) != NULL)
145
171
  {
146
172
    if ((*prev)->left < length &&
147
 
        mem_root->first_block_usage++ >= MAX_BLOCK_USAGE_BEFORE_DROP &&
148
 
        (*prev)->left < MAX_BLOCK_TO_DROP)
 
173
        mem_root->first_block_usage++ >= ALLOC_MAX_BLOCK_USAGE_BEFORE_DROP &&
 
174
        (*prev)->left < ALLOC_MAX_BLOCK_TO_DROP)
149
175
    {
150
176
      next= *prev;
151
177
      *prev= next->next;                        /* Remove block from list */
159
185
  if (! next)
160
186
  {                                             /* Time to alloc new block */
161
187
    block_size= mem_root->block_size * (mem_root->block_num >> 2);
162
 
    get_size= length+ALIGN_SIZE(sizeof(memory::internal::UsedMemory));
 
188
    get_size= length+ALIGN_SIZE(sizeof(USED_MEM));
163
189
    get_size= max(get_size, block_size);
164
190
 
165
 
    if (!(next = static_cast<memory::internal::UsedMemory *>(malloc(get_size))))
 
191
    if (!(next = (USED_MEM*) my_malloc(get_size,MYF(MY_WME | ME_FATALERROR))))
166
192
    {
167
193
      if (mem_root->error_handler)
168
194
        (*mem_root->error_handler)();
169
 
      return NULL;
 
195
      return((void*) 0);                      /* purecov: inspected */
170
196
    }
171
197
    mem_root->block_num++;
172
198
    next->next= *prev;
173
199
    next->size= get_size;
174
 
    next->left= get_size-ALIGN_SIZE(sizeof(memory::internal::UsedMemory));
 
200
    next->left= get_size-ALIGN_SIZE(sizeof(USED_MEM));
175
201
    *prev=next;
176
202
  }
177
203
 
178
 
  point= (unsigned char*) ((char*) next+ (next->size-next->left));
 
204
  point= (uchar*) ((char*) next+ (next->size-next->left));
179
205
  /*TODO: next part may be unneded due to mem_root->first_block_usage counter*/
180
206
  if ((next->left-= length) < mem_root->min_malloc)
181
207
  {                                             /* Full block */
185
211
    mem_root->first_block_usage= 0;
186
212
  }
187
213
  return((void*) point);
 
214
#endif
188
215
}
189
216
 
190
217
 
207
234
    in case of success or NULL if out of memory.
208
235
*/
209
236
 
210
 
void *memory::multi_alloc_root(memory::Root *root, ...)
 
237
void *multi_alloc_root(MEM_ROOT *root, ...)
211
238
{
212
239
  va_list args;
213
240
  char **ptr, *start, *res;
222
249
  }
223
250
  va_end(args);
224
251
 
225
 
  if (!(start= (char*) memory::alloc_root(root, tot_length)))
226
 
    return(0);
 
252
  if (!(start= (char*) alloc_root(root, tot_length)))
 
253
    return(0);                            /* purecov: inspected */
227
254
 
228
255
  va_start(args, root);
229
256
  res= start;
241
268
 
242
269
/* Mark all data in blocks free for reusage */
243
270
 
244
 
static inline void mark_blocks_free(memory::Root* root)
 
271
static inline void mark_blocks_free(MEM_ROOT* root)
245
272
{
246
 
  memory::internal::UsedMemory *next;
247
 
  memory::internal::UsedMemory **last;
 
273
  register USED_MEM *next;
 
274
  register USED_MEM **last;
248
275
 
249
276
  /* iterate through (partially) free blocks, mark them free */
250
277
  last= &root->free;
251
278
  for (next= root->free; next; next= *(last= &next->next))
252
279
  {
253
 
    next->left= next->size - ALIGN_SIZE(sizeof(memory::internal::UsedMemory));
 
280
    next->left= next->size - ALIGN_SIZE(sizeof(USED_MEM));
254
281
    TRASH_MEM(next);
255
282
  }
256
283
 
260
287
  /* now go through the used blocks and mark them free */
261
288
  for (; next; next= next->next)
262
289
  {
263
 
    next->left= next->size - ALIGN_SIZE(sizeof(memory::internal::UsedMemory));
 
290
    next->left= next->size - ALIGN_SIZE(sizeof(USED_MEM));
264
291
    TRASH_MEM(next);
265
292
  }
266
293
 
271
298
 
272
299
 
273
300
/*
274
 
  Deallocate everything used by memory::alloc_root or just move
 
301
  Deallocate everything used by alloc_root or just move
275
302
  used blocks to free list if called with MY_USED_TO_FREE
276
303
 
277
304
  SYNOPSIS
279
306
      root              Memory root
280
307
      MyFlags           Flags for what should be freed:
281
308
 
282
 
        MARK_BLOCKS_FREED       Don't free blocks, just mark them free
283
 
        KEEP_PREALLOC           If this is not set, then free also the
 
309
        MY_MARK_BLOCKS_FREED    Don't free blocks, just mark them free
 
310
        MY_KEEP_PREALLOC        If this is not set, then free also the
284
311
                                preallocated block
285
312
 
286
313
  NOTES
289
316
    It's also safe to call this multiple times with the same mem_root.
290
317
*/
291
318
 
292
 
void memory::free_root(memory::Root *root, myf MyFlags)
 
319
void free_root(MEM_ROOT *root, myf MyFlags)
293
320
{
294
 
  memory::internal::UsedMemory *next,*old;
 
321
  register USED_MEM *next,*old;
295
322
 
296
 
  if (MyFlags & memory::MARK_BLOCKS_FREE)
 
323
  if (MyFlags & MY_MARK_BLOCKS_FREE)
297
324
  {
298
325
    mark_blocks_free(root);
299
326
    return;
300
327
  }
301
 
  if (!(MyFlags & memory::KEEP_PREALLOC))
 
328
  if (!(MyFlags & MY_KEEP_PREALLOC))
302
329
    root->pre_alloc=0;
303
330
 
304
331
  for (next=root->used; next ;)
305
332
  {
306
333
    old=next; next= next->next ;
307
334
    if (old != root->pre_alloc)
308
 
      free(old);
 
335
      my_free(old,MYF(0));
309
336
  }
310
337
  for (next=root->free ; next ;)
311
338
  {
312
339
    old=next; next= next->next;
313
340
    if (old != root->pre_alloc)
314
 
      free(old);
 
341
      my_free(old,MYF(0));
315
342
  }
316
343
  root->used=root->free=0;
317
344
  if (root->pre_alloc)
318
345
  {
319
346
    root->free=root->pre_alloc;
320
 
    root->free->left=root->pre_alloc->size-ALIGN_SIZE(sizeof(memory::internal::UsedMemory));
 
347
    root->free->left=root->pre_alloc->size-ALIGN_SIZE(sizeof(USED_MEM));
321
348
    TRASH_MEM(root->pre_alloc);
322
349
    root->free->next=0;
323
350
  }
330
357
  Find block that contains an object and set the pre_alloc to it
331
358
*/
332
359
 
333
 
void memory::set_prealloc_root(memory::Root *root, char *ptr)
 
360
void set_prealloc_root(MEM_ROOT *root, char *ptr)
334
361
{
335
 
  memory::internal::UsedMemory *next;
 
362
  USED_MEM *next;
336
363
  for (next=root->used; next ; next=next->next)
337
364
  {
338
365
    if ((char*) next <= ptr && (char*) next + next->size > ptr)
352
379
}
353
380
 
354
381
 
355
 
char *memory::strdup_root(memory::Root *root, const char *str)
 
382
char *strdup_root(MEM_ROOT *root, const char *str)
356
383
{
357
384
  return strmake_root(root, str, strlen(str));
358
385
}
359
386
 
360
387
 
361
 
char *memory::strmake_root(memory::Root *root, const char *str, size_t len)
 
388
char *strmake_root(MEM_ROOT *root, const char *str, size_t len)
362
389
{
363
390
  char *pos;
364
 
  if ((pos=(char *)memory::alloc_root(root,len+1)))
 
391
  if ((pos=alloc_root(root,len+1)))
365
392
  {
366
393
    memcpy(pos,str,len);
367
394
    pos[len]=0;
370
397
}
371
398
 
372
399
 
373
 
void *memory::memdup_root(memory::Root *root, const void *str, size_t len)
 
400
void *memdup_root(MEM_ROOT *root, const void *str, size_t len)
374
401
{
375
 
  void *pos;
376
 
  if ((pos=memory::alloc_root(root,len)))
 
402
  char *pos;
 
403
  if ((pos=alloc_root(root,len)))
377
404
    memcpy(pos,str,len);
378
405
  return pos;
379
406
}
380
 
 
381
 
} /* namespace drizzled */