CUBRID Engine  latest
area_alloc.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 /*
20  * area_alloc.c - Area memory manager
21  *
22  * Note:
23  * Allocation areas provide a way to block allocate structures and maintain
24  * a free list. Useful for small structures that are used frequently.
25  * Used for allocation and freeing of many small objects of the same size.
26  *
27  * These areas are NOT allocated within the "workspace" memory so that
28  * they can be used for structures that need to serve as roots to the
29  * garbage collector.
30  */
31 
32 #ident "$Id$"
33 
34 #include "config.h"
35 
36 #include <stdio.h>
37 #include <string.h>
38 #include <assert.h>
39 
40 #include "area_alloc.h"
41 #include "set_object.h"
42 
43 #if !defined (SERVER_MODE)
44 #include "work_space.h"
45 #endif /* !defined (SERVER_MODE) */
46 
47 #if !defined (SERVER_MODE)
48 #define pthread_mutex_init(a, b)
49 #define pthread_mutex_destroy(a)
50 #define pthread_mutex_lock(a) 0
51 #define pthread_mutex_unlock(a)
52 static int rv;
53 #endif
54 
55 #if !defined (NDEBUG)
56 /* The size of the prefix containing allocation status, if we're
57  on a machine that requires double allignment of structures, we
58  may have to make this sizeof(double) */
59 #define AREA_PREFIX_SIZE sizeof(double)
60 
61 enum
62 {
64  AREA_PREFIX_FREED = 0x01010101
65 };
66 #endif /* !NDEBUG */
67 
68 /*
69  * Area_list - Global list of areas
70  */
71 static AREA *area_List = NULL;
72 #if defined (SERVER_MODE)
73 pthread_mutex_t area_List_lock = PTHREAD_MUTEX_INITIALIZER;
74 #endif
75 
76 #if defined (SERVER_MODE)
77 #define LF_AREA_BITMAP_USAGE_RATIO LF_BITMAP_95PERCENTILE_USAGE_RATIO
78 #else
79 #define LF_AREA_BITMAP_USAGE_RATIO LF_BITMAP_FULL_USAGE_RATIO
80 #endif
81 
82 /*
83  * Volatile access to a variable
84  */
85 #define VOLATILE_ACCESS(v,t) (*((t volatile *) &(v)))
86 
87 static void area_info (AREA * area, FILE * fp);
91 static AREA_BLOCK *area_find_block (AREA * area, const void *ptr);
92 
93 /*
94  * area_init - Initialize the area manager
95  * return: none
96  *
97  * Note: Will be called during system startup
98  */
99 void
100 area_init (void)
101 {
102 #define ER_AREA_ALREADY_STARTED ER_GENERIC_ERROR
103  if (area_List != NULL)
104  {
106  return;
107  }
108 
109  area_List = NULL;
110 }
111 
112 /*
113  * area_final - Shut down the area manager
114  * return: none
115  *
116  * Note: Will be called during system shutdown
117  */
118 void
120 {
121  AREA *area, *next;
122 
123  for (area = area_List, next = NULL; area != NULL; area = next)
124  {
125  next = area->next;
126  area_flush (area);
127  free_and_init (area);
128  }
129  area_List = NULL;
130 
131  set_area_reset ();
132 
133  pthread_mutex_destroy (&area_List_lock);
134 }
135 
136 /*
137  * area_create - Build a new area and add it to the global list
138  * return: created AREA or NULL if fail
139  * name(in):
140  * element_size(in):
141  * alloc_count(in):
142  *
143  * Note:
144  */
145 AREA *
146 area_create (const char *name, size_t element_size, size_t alloc_count)
147 {
148  AREA *area;
149  size_t adjust;
150 #if defined (SERVER_MODE)
151  int rv;
152 #endif /* SERVER_MODE */
153 
154  area = (AREA *) malloc (sizeof (AREA));
155  if (area == NULL)
156  {
158  return NULL;
159  }
160  area->blockset_list = NULL;
161 
162  if (name == NULL)
163  {
164  area->name = NULL;
165  }
166  else
167  {
168  area->name = strdup (name);
169  if (area->name == NULL)
170  {
172  goto error;
173  }
174  }
175 
176 #if !defined (NDEBUG)
177  /* Reserve space for memory checking */
178  element_size += AREA_PREFIX_SIZE;
179 #endif /* !NDEBUG */
180 
181  /* always make sure element size is a double word multiple */
182  adjust = element_size % 8;
183  if (adjust)
184  {
185  element_size += 8 - adjust;
186  }
187  area->element_size = element_size;
188 
189  /* adjust alloc count for lf_bitmap */
190  area->alloc_count = LF_BITMAP_COUNT_ALIGN (alloc_count);
191  area->block_size = area->element_size * area->alloc_count;
192 
193  area->n_allocs = 0;
194  area->n_frees = 0;
195 #if defined (SERVER_MODE)
196  area->failure_function = NULL;
197 #else
199 #endif
200 
201  area->blockset_list = area_alloc_blockset (area);
202  if (area->blockset_list == NULL)
203  {
204  goto error;
205  }
206 
207  area->hint_block = area_alloc_block (area);
208  if (area->hint_block == NULL)
209  {
210  goto error;
211  }
212  area->blockset_list->items[0] = area->hint_block;
213  area->blockset_list->used_count++;
214 
216 
217  rv = pthread_mutex_lock (&area_List_lock);
218  area->next = area_List;
219  area_List = area;
220  pthread_mutex_unlock (&area_List_lock);
221 
222  return area;
223 
224 error:
225 
226  if (area->name)
227  {
228  free_and_init (area->name);
229  }
230 
231  if (area->blockset_list != NULL)
232  {
234  }
235 
236  free_and_init (area);
237 
238  return NULL;
239 }
240 
241 /*
242  * area_destroy - Removes an area
243  * return: none
244  * area(in): AREA tp destroy
245  */
246 void
248 {
249  AREA *a, *prev;
250 #if defined(SERVER_MODE)
251  int rv;
252 #endif /* SERVER_MODE */
253 
254  assert (area != NULL);
255 
256  rv = pthread_mutex_lock (&area_List_lock);
257 
258  for (prev = NULL, a = area_List; a != NULL && a != area; a = a->next)
259  {
260  prev = a;
261  }
262 
263  if (a != NULL)
264  {
265  if (prev == NULL)
266  {
267  area_List = a->next;
268  }
269  else
270  {
271  prev->next = a->next;
272  }
273  }
274 
275  pthread_mutex_unlock (&area_List_lock);
276 
277  area_flush (area);
278 
279  free_and_init (area);
280 }
281 
282 /*
283  * area_alloc_block - Allocate a new block for an area
284  * return: the address of area block, if error, return NULL.
285  * area(in): AREA
286  * thrd_index(in): thread index
287  *
288  * Note: this is called by area_alloc, and lock is also held by area_alloc
289  */
290 static AREA_BLOCK *
292 {
294  size_t total;
295 
296  assert (area != NULL);
297 
298  total = area->block_size + sizeof (AREA_BLOCK);
299 
300  new_block = (AREA_BLOCK *) malloc (total);
301  if (new_block == NULL)
302  {
304  if (area->failure_function != NULL)
305  {
306  (*(area->failure_function)) ();
307  }
308 
309  return NULL;
310  }
311 
313  assert ((int) area->alloc_count == new_block->bitmap.entry_count);
314 
315  new_block->data = ((char *) new_block) + sizeof (AREA_BLOCK);
316 
317  return new_block;
318 }
319 
320 /*
321  * area_alloc_blockset - Allocate a new blockset node
322  * return: the address of area blockset, if error, return NULL.
323  * area(in): AREA
324  *
325  */
326 static AREA_BLOCKSET_LIST *
328 {
329  AREA_BLOCKSET_LIST *new_blockset;
330 
331  new_blockset = (AREA_BLOCKSET_LIST *) malloc (sizeof (AREA_BLOCKSET_LIST));
332  if (new_blockset == NULL)
333  {
335  if (area->failure_function != NULL)
336  {
337  (*(area->failure_function)) ();
338  }
339 
340  return NULL;
341  }
342 
343  new_blockset->next = NULL;
344  new_blockset->used_count = 0;
345  memset ((void *) new_blockset->items, 0, sizeof (sizeof (AREA_BLOCK *) * AREA_BLOCKSET_SIZE));
346 
347  return new_blockset;
348 }
349 
350 /*
351  * area_alloc - Allocate a new element from an area
352  * return: pointer to the element allocated
353  * area(in):
354  *
355  * Note: The element will be taken from the area's free list,
356  * otherwise a new block will be allocated and the element
357  * taken from there
358  */
359 void *
361 {
362  AREA_BLOCKSET_LIST *blockset;
363  AREA_BLOCK *block, *hint_block;
364  int used_count, i, entry_idx;
365  char *entry_ptr;
366 #if defined(SERVER_MODE)
367  int rv;
368 #endif /* SERVER_MODE */
369 #if !defined (NDEBUG)
370  int *prefix;
371 #endif /* !NDEBUG */
372 
373  assert (area != NULL);
374 
375  /* Step 1: find a free entry from the hint block */
376  hint_block = VOLATILE_ACCESS (area->hint_block, AREA_BLOCK *);
377  entry_idx = hint_block->bitmap.get_entry ();
378  if (entry_idx != -1)
379  {
380  block = hint_block;
381  goto found;
382  }
383 
384  /* Step 2: if not found, find a free entry from the blockset lists */
385  for (blockset = area->blockset_list; blockset != NULL;
386  blockset = VOLATILE_ACCESS (blockset->next, AREA_BLOCKSET_LIST *))
387  {
388  used_count = VOLATILE_ACCESS (blockset->used_count, int);
389  for (i = 0; i < used_count; i++)
390  {
391  block = VOLATILE_ACCESS (blockset->items[i], AREA_BLOCK *);
392 
393  entry_idx = block->bitmap.get_entry ();
394  if (entry_idx != -1)
395  {
396  /* change the hint block */
397  hint_block = VOLATILE_ACCESS (area->hint_block, AREA_BLOCK *);
398  if (LF_BITMAP_IS_FULL (&hint_block->bitmap) && !LF_BITMAP_IS_FULL (&block->bitmap))
399  {
400  ATOMIC_CAS_ADDR (&area->hint_block, hint_block, block);
401  }
402 
403  goto found;
404  }
405  }
406  }
407 
408  /* Step 3: if not found, add a new block. Then find free entry in this new block.
409  * Only one thread is allowed to add a new block at a moment.
410  */
411  rv = pthread_mutex_lock (&area->area_mutex);
412 
413  if (area->hint_block != hint_block)
414  {
415  /* someone may change the hint block */
416  block = area->hint_block;
417  entry_idx = block->bitmap.get_entry ();
418  if (entry_idx != -1)
419  {
421  goto found;
422  }
423  }
424 
425  block = area_alloc_block (area);
426  if (block == NULL)
427  {
429  /* error has been set */
430  return NULL;
431  }
432 
433  /* alloc free entry from this new block */
434  entry_idx = block->bitmap.get_entry ();
435  assert (entry_idx != -1);
436 
437  if (area_insert_block (area, block) != NO_ERROR)
438  {
439  block->bitmap.destroy ();
440  free_and_init (block);
441 
443  /* error has been set */
444  return NULL;
445  }
446 
447  /* always set new block as hint_block */
448  area->hint_block = block;
449 
451 
452 found:
453 
454 #if defined(SERVER_MODE)
455  /* do not count in SERVER_MODE */
456  /* ATOMIC_INC_32 (&area->n_allocs, 1); */
457 #else
458  area->n_allocs++;
459 #endif
460 
461  entry_ptr = block->data + area->element_size * entry_idx;
462 
463 #if !defined (NDEBUG)
464  prefix = (int *) entry_ptr;
465  *prefix = AREA_PREFIX_INITED;
466 
467  entry_ptr += AREA_PREFIX_SIZE;
468 #endif /* !NDEBUG */
469 
470  assert (entry_ptr < (block->data + area->block_size));
471 
472  return ((void *) entry_ptr);
473 }
474 
475 /*
476  * area_validate - validate that a pointer is within range in an area
477  * return: NO_ERROR if ok (address in range) or ER_AREA_ILLEGAL_POINTER
478  * area(in): AREA
479  * address(in): pointer to check
480  *
481  * Note: ER_AREA_ILLEGAL_POINTER will be set if fails.
482  * This does not guarentee that the pointer is alligned
483  * correctly to the start of an element, only that it points into one
484  * of the area blocks.
485  */
486 int
487 area_validate (AREA * area, const void *address)
488 {
489  AREA_BLOCK *p;
490  int error = NO_ERROR;
491 
492  assert (area != NULL);
493 
494  p = area_find_block (area, address);
495  if (p == NULL)
496  {
497  /* need more specific error here */
499  error = ER_AREA_ILLEGAL_POINTER;
500  }
501 
502  return error;
503 }
504 
505 /*
506  * area_free - Free an element in an area
507  * return: error code
508  * area(in): AREA
509  * ptr(in): pointer to the element
510  *
511  * Note: Validation is performed; the element is simply pushed on the free list
512  */
513 int
514 area_free (AREA * area, void *ptr)
515 {
516  AREA_BLOCK *block, *hint_block;
517  char *entry_ptr;
518  int entry_idx;
519  int offset = -1;
520 #if !defined (NDEBUG)
521  int *prefix;
522 #endif /* !NDEBUG */
523 
524  assert (area != NULL);
525 
526  if (ptr == NULL)
527  {
529  assert (ptr != NULL);
531  }
532 
533 #if !defined (NDEBUG)
534  entry_ptr = ((char *) ptr) - AREA_PREFIX_SIZE;
535 #else
536  entry_ptr = (char *) ptr;
537 #endif /* !NDEBUG */
538 
539  block = area_find_block (area, (const void *) entry_ptr);
540  if (block == NULL)
541  {
543  assert (false);
545  }
546 
547  offset = (int) (entry_ptr - block->data);
548  if (offset < 0 || offset % area->element_size != 0)
549  {
551  assert (false);
553  }
554 
555 #if !defined (NDEBUG)
556  prefix = (int *) entry_ptr;
557  if ((*prefix) != AREA_PREFIX_INITED)
558  {
560  assert ((*prefix) == AREA_PREFIX_INITED);
561  return ER_AREA_FREE_TWICE;
562  }
563  *prefix = AREA_PREFIX_FREED;
564 #endif /* !NDEBUG */
565 
566  entry_idx = offset / (int) area->element_size;
567 
568  assert (entry_idx >= 0 && entry_idx < (int) area->alloc_count);
569 
570  block->bitmap.free_entry (entry_idx);
571 
572  /* change hint block if needed */
573  hint_block = VOLATILE_ACCESS (area->hint_block, AREA_BLOCK *);
574  if (LF_BITMAP_IS_FULL (&hint_block->bitmap) && !LF_BITMAP_IS_FULL (&block->bitmap))
575  {
576  ATOMIC_CAS_ADDR (&area->hint_block, hint_block, block);
577  }
578 
579 #if defined(SERVER_MODE)
580  /* do not count in SERVER_MODE */
581  /* ATOMIC_INC_32 (&area->n_frees, 1); */
582 #else
583  area->n_frees++;
584 #endif
585 
586  return NO_ERROR;
587 }
588 
589 /*
590  * area_flush - Free all storage allocated for an area
591  * return: none
592  * area(in): AREA to free
593  *
594  * Note: Normally called as part of final
595  */
596 void
598 {
599  AREA_BLOCKSET_LIST *blockset, *next_blockset;
600  AREA_BLOCK *block;
601  int i;
602 
603  assert (area != NULL);
604 
605  for (blockset = area->blockset_list; blockset != NULL; blockset = next_blockset)
606  {
607  next_blockset = blockset->next;
608 
609  for (i = 0; i < blockset->used_count; i++)
610  {
611  block = blockset->items[i];
612 
613  block->bitmap.destroy ();
614  free_and_init (block);
615  blockset->items[i] = NULL;
616  }
617 
618  free_and_init (blockset);
619  }
620  area->blockset_list = NULL;
621 
623 
624  if (area->name != NULL)
625  {
626  free_and_init (area->name);
627  }
628 
629 }
630 
631 /*
632  * area_add_block --- insert block into the blockset list
633  * return: none
634  * area(in): area descriptor
635  * new_block(in): the new area_block pointer
636  *
637  * Note: This function is protected by area_mutex, which mean only
638  * 1 thread can insert block in the same time.
639  */
640 static int
642 {
643  AREA_BLOCKSET_LIST **last_blockset_p;
644  AREA_BLOCKSET_LIST *blockset, *new_blockset;
645  int used_count;
646 
647  assert (area != NULL && new_block != NULL);
648 
649  last_blockset_p = &area->blockset_list;
650  /* find an available blockset and insert new_block into it */
651  for (blockset = area->blockset_list; blockset != NULL; blockset = blockset->next)
652  {
653  last_blockset_p = &blockset->next;
654 
655  used_count = blockset->used_count;
656  if (used_count == AREA_BLOCKSET_SIZE)
657  {
658  /* no room */
659  continue;
660  }
661  /* each blockset owns one block at least */
662  assert (used_count >= 1);
663 
664  /* If it fits, insert new_block to the last slot of this blockset. We don't shift/re-sort the blockset to manage
665  * sorted order. Our policy may require more space but greatly reduces the complexity of logic. */
666  if (blockset->items[used_count - 1] < new_block)
667  {
668  blockset->items[used_count] = new_block;
669 
670  /* Use full barrier to ensure that above assignment done before increase used_count */
671  ATOMIC_INC_32 (&blockset->used_count, 1);
672 
673  return NO_ERROR;
674  }
675  }
676 
677  /* If there's no available blockset, we need to allocate a new blockset */
678  new_blockset = area_alloc_blockset (area);
679  if (new_blockset == NULL)
680  {
681  assert (er_errid () != NO_ERROR);
682  return er_errid ();
683  }
684 
685  /* insert new_block to the first slot */
686  new_blockset->items[0] = new_block;
687 
688  /* Use full barrier to ensure that above assignment done before increase used_count */
689  ATOMIC_INC_32 (&new_blockset->used_count, 1);
690 
691  /* append the new blockset to the end of blockset list */
692  assert ((*last_blockset_p) == NULL);
693  *last_blockset_p = new_blockset;
694 
695  return NO_ERROR;
696 }
697 
698 /*
699  * area_find_block -- find related block in blockset list.
700  *
701  * return: the related block pointer, if not found, return NULL
702  * area(in): area descriptor
703  * ptr(in): the entry pointer
704  *
705  * Note: This function does not require area_mutex.
706  */
707 static AREA_BLOCK *
708 area_find_block (AREA * area, const void *ptr)
709 {
710  AREA_BLOCKSET_LIST *blockset;
711  AREA_BLOCK *first_block, *last_block, *block;
712  int middle, left, right, pos;
713  int used_count;
714 
715  /* find the related block in blockset list */
716  for (blockset = area->blockset_list; blockset != NULL;
717  blockset = VOLATILE_ACCESS (blockset->next, AREA_BLOCKSET_LIST *))
718  {
719  used_count = VOLATILE_ACCESS (blockset->used_count, int);
720  /* each blocskset owns one block at least */
721  assert (used_count >= 1);
722 
723  first_block = blockset->items[0];
724  if ((char *) ptr < first_block->data)
725  {
726  continue; /* less than min address */
727  }
728 
729  last_block = VOLATILE_ACCESS (blockset->items[used_count - 1], AREA_BLOCK *);
730  if (last_block->data + area->block_size <= (char *) ptr)
731  {
732  continue; /* large than max address */
733  }
734 
735  assert ((first_block->data <= (char *) ptr) && ((char *) ptr < last_block->data + area->block_size));
736 
737  left = 0;
738  right = used_count - 1;
739 
740  /* binary search in this blockset */
741  while (left <= right)
742  {
743  middle = (left + right) / 2;
744 
745  block = VOLATILE_ACCESS (blockset->items[middle], AREA_BLOCK *);
746  if (block->data > (char *) ptr)
747  {
748  right = middle - 1;
749  }
750  else
751  {
752  left = middle + 1;
753  }
754  }
755  pos = right;
756 
757  if (pos < 0 || pos >= AREA_BLOCKSET_SIZE)
758  {
759  /* impossible to here */
761  assert (false);
762  return NULL;
763  }
764 
765  block = VOLATILE_ACCESS (blockset->items[pos], AREA_BLOCK *);
766  if ((block->data <= (char *) ptr) && ((char *) ptr < block->data + area->block_size))
767  {
768  return block;
769  }
770  }
771 
772  /* not found */
773  return NULL;
774 }
775 
776 /*
777  * area_info - Display information about an area
778  * return: none
779  * area(in): area descriptor
780  * fp(in):
781  */
782 static void
783 area_info (AREA * area, FILE * fp)
784 {
785  AREA_BLOCKSET_LIST *blockset;
786  AREA_BLOCK *block;
787  size_t nblocksets, nblocks, bytes, elements, used, unused;
788  size_t min_blocks_in_set, avg_blocks_in_set, max_blocks_in_set;
789  size_t nallocs = 0, nfrees = 0;
790  int i;
791 
792  assert (area != NULL && fp != NULL);
793 
794  nblocksets = nblocks = bytes = elements = used = unused = 0;
795  min_blocks_in_set = AREA_BLOCKSET_SIZE;
796  max_blocks_in_set = 0;
797 
798  for (blockset = area->blockset_list; blockset != NULL; blockset = blockset->next)
799  {
800  nblocksets++;
801 
802  for (i = 0; i < blockset->used_count; i++)
803  {
804  block = blockset->items[i];
805 
806  nblocks++;
807  used += block->bitmap.entry_count_in_use;
808  bytes += area->block_size + sizeof (AREA_BLOCK);
809  }
810 
811  if ((size_t) blockset->used_count < min_blocks_in_set)
812  {
813  min_blocks_in_set = blockset->used_count;
814  }
815  if ((size_t) blockset->used_count > max_blocks_in_set)
816  {
817  max_blocks_in_set = blockset->used_count;
818  }
819  }
820  avg_blocks_in_set = nblocks / nblocksets;
821 
822  elements = (nblocks * area->alloc_count);
823  unused = elements - used;
824 
825  nallocs = area->n_allocs;
826  nfrees = area->n_frees;
827 
828  fprintf (fp, "Area: %s\n", area->name);
829 #if !defined (NDEBUG)
830  fprintf (fp, " %lld bytes/element ", (long long) area->element_size - AREA_PREFIX_SIZE);
831  fprintf (fp, "(plus %d bytes overhead), ", (int) AREA_PREFIX_SIZE);
832 #else
833  fprintf (fp, " %lld bytes/element, ", (long long) area->element_size);
834 #endif
835  fprintf (fp, "%lld elements/block, %lld blocks/blockset\n", (long long) area->alloc_count,
836  (long long) AREA_BLOCKSET_SIZE);
837 
838  fprintf (fp, " %lld blocksets, usage stats:" " MIN %lld, AVG %lld, MAX %lld\n", (long long) nblocksets,
839  (long long) min_blocks_in_set, (long long) avg_blocks_in_set, (long long) max_blocks_in_set);
840 
841  fprintf (fp, " %lld blocks, %lld bytes, %lld elements," " %lld unused, %lld in use\n", (long long) nblocks,
842  (long long) bytes, (long long) elements, (long long) unused, (long long) used);
843 
844  fprintf (fp, " %lld total allocs, %lld total frees\n", (long long) nallocs, (long long) nfrees);
845 }
846 
847 /*
848  * area_dump - Print descriptions of all areas.
849  * return: none
850  * fp(in):
851  */
852 void
853 area_dump (FILE * fp)
854 {
855  AREA *area;
856 #if defined(SERVER_MODE)
857  int rv;
858 #endif /* SERVER_MODE */
859 
860  if (fp == NULL)
861  {
862  fp = stdout;
863  }
864 
865  rv = pthread_mutex_lock (&area_List_lock);
866 
867  for (area = area_List; area != NULL; area = area->next)
868  {
869  area_info (area, fp);
870  }
871 
872  pthread_mutex_unlock (&area_List_lock);
873 }
#define AREA_PREFIX_SIZE
Definition: area_alloc.c:59
LF_BITMAP bitmap
Definition: area_alloc.h:53
#define NO_ERROR
Definition: error_code.h:46
#define ER_AREA_ALREADY_STARTED
AREA_BLOCK * hint_block
Definition: area_alloc.h:84
void area_destroy(AREA *area)
Definition: area_alloc.c:247
#define pthread_mutex_init(a, b)
Definition: area_alloc.c:48
static AREA_BLOCK * area_find_block(AREA *area, const void *ptr)
Definition: area_alloc.c:708
#define pthread_mutex_unlock(a)
Definition: area_alloc.c:51
static AREA * area_List
Definition: area_alloc.c:71
void free_entry(int entry_idx)
size_t alloc_count
Definition: area_alloc.h:80
static AREA_BLOCK * area_alloc_block(AREA *area)
Definition: area_alloc.c:291
char * data
Definition: area_alloc.h:54
static int area_insert_block(AREA *area, AREA_BLOCK *new_block)
Definition: area_alloc.c:641
AREA * next
Definition: area_alloc.h:76
static AREA_BLOCKSET_LIST * area_alloc_blockset(AREA *area)
Definition: area_alloc.c:327
size_t n_frees
Definition: area_alloc.h:89
#define LF_BITMAP_IS_FULL(bitmap)
int er_errid(void)
struct area_block AREA_BLOCK
Definition: area_alloc.h:50
AREA_BLOCKSET_LIST * next
Definition: area_alloc.h:65
AREA * area_create(const char *name, size_t element_size, size_t alloc_count)
Definition: area_alloc.c:146
#define LF_BITMAP_COUNT_ALIGN(count)
static void area_info(AREA *area, FILE *fp)
Definition: area_alloc.c:783
void area_init(void)
Definition: area_alloc.c:100
void er_set(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
int area_validate(AREA *area, const void *address)
Definition: area_alloc.c:487
#define ER_AREA_ILLEGAL_POINTER
Definition: error_code.h:411
AREA_BLOCKSET_LIST * blockset_list
Definition: area_alloc.h:83
#define assert(x)
void(* failure_function)(void)
Definition: area_alloc.h:91
size_t element_size
Definition: area_alloc.h:79
#define ER_OUT_OF_VIRTUAL_MEMORY
Definition: error_code.h:50
std::atomic< int > entry_count_in_use
void set_area_reset()
Definition: set_object.c:205
static int rv
Definition: area_alloc.c:52
#define NULL
Definition: freelistheap.h:34
static const LF_BITMAP_STYLE LF_BITMAP_LIST_OF_CHUNKS
pthread_mutex_t area_mutex
Definition: area_alloc.h:85
size_t n_allocs
Definition: area_alloc.h:88
void area_dump(FILE *fp)
Definition: area_alloc.c:853
static void error(const char *msg)
Definition: gencat.c:331
static DB_VALUE * new_block(long n)
Definition: set_object.c:224
#define ARG_FILE_LINE
Definition: error_manager.h:44
#define AREA_BLOCKSET_SIZE
Definition: area_alloc.h:42
#define free_and_init(ptr)
Definition: memory_alloc.h:147
#define strlen(s1)
Definition: intl_support.c:43
size_t block_size
Definition: area_alloc.h:81
void * area_alloc(AREA *area)
Definition: area_alloc.c:360
#define ER_AREA_FREE_TWICE
Definition: error_code.h:412
int area_free(AREA *area, void *ptr)
Definition: area_alloc.c:514
AREA_BLOCK * items[AREA_BLOCKSET_SIZE]
Definition: area_alloc.h:66
int i
Definition: dynamic_load.c:954
char * strdup(const char *str)
Definition: porting.c:901
#define pthread_mutex_lock(a)
Definition: area_alloc.c:50
void area_final(void)
Definition: area_alloc.c:119
#define VOLATILE_ACCESS(v, t)
Definition: area_alloc.c:85
#define LF_AREA_BITMAP_USAGE_RATIO
Definition: area_alloc.c:79
void area_flush(AREA *area)
Definition: area_alloc.c:597
void ws_abort_transaction(void)
Definition: work_space.c:201
const char ** p
Definition: dynamic_load.c:945
void init(chunking_style style, int entries_count, float usage_ratio)
char * name
Definition: area_alloc.h:78
#define pthread_mutex_destroy(a)
Definition: area_alloc.c:49