Skip to content

File memory_alloc.h

File List > base > memory_alloc.h

Go to the documentation of this file

/*
 * Copyright 2008 Search Solution Corporation
 * Copyright 2016 CUBRID Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */


/*
 * memory_alloc.h - Memory allocation module
 */

#ifndef _MEMORY_ALLOC_H_
#define _MEMORY_ALLOC_H_

#ident "$Id$"

#include "config.h"

#include "dbtype_def.h"
#include "thread_compat.hpp"

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <sys/types.h>
#include <stddef.h>
#include <string.h>
#if !defined(WINDOWS)
#include <stdint.h>
#endif

#if defined (__cplusplus)
#include <memory>
#include <functional>
#endif
/* ***IMPORTANT!!***
 * memory_wrapper.hpp has a restriction that it must locate at the end of including section
 * because the user-defined new for overloaded format can make build error in glibc
 * when glibc header use "placement new" or another overloaded format of new.
 * So memory_wrapper.hpp cannot be included in header file, but memory_cwrapper.h can be included.
 * You can include memory_cwrapper.h in a header file when the header file use allocation function. */
#include "memory_cwrapper.h"

/* Ceiling of positive division */
#define CEIL_PTVDIV(dividend, divisor) \
        (((dividend) == 0) ? 0 : (((dividend) - 1) / (divisor)) + 1)

/* Make sure that sizeof returns and integer, so I can use in the operations */
#define DB_SIZEOF(val)          (sizeof(val))

/*
 * Macros related to alignments
 */
#define CHAR_ALIGNMENT          sizeof(char)
#define SHORT_ALIGNMENT         sizeof(short)
#define INT_ALIGNMENT           sizeof(int)
#define LONG_ALIGNMENT          sizeof(long)
#define FLOAT_ALIGNMENT         sizeof(float)
#define DOUBLE_ALIGNMENT        sizeof(double)
#if __WORDSIZE == 32
#define PTR_ALIGNMENT       4
#else
#define PTR_ALIGNMENT       8
#endif
#define MAX_ALIGNMENT           DOUBLE_ALIGNMENT

#if defined(NDEBUG)
#define PTR_ALIGN(addr, boundary) \
        ((char *)((((UINTPTR)(addr) + ((UINTPTR)((boundary)-1)))) \
                  & ~((UINTPTR)((boundary)-1))))
#else
#define PTR_ALIGN(addr, boundary) \
        (memset((void*)(addr), 0,\
       DB_WASTED_ALIGN((UINTPTR)(addr), (UINTPTR)(boundary))),\
        (char *)((((UINTPTR)(addr) + ((UINTPTR)((boundary)-1)))) \
                  & ~((UINTPTR)((boundary)-1))))
#endif

#define DB_ALIGN(offset, align) \
        (((offset) + (align) - 1) & ~((align) - 1))

#define DB_ALIGN_BELOW(offset, align) \
        ((offset) & ~((align) - 1))

#define DB_WASTED_ALIGN(offset, align) \
        (DB_ALIGN((offset), (align)) - (offset))

#define DB_ATT_ALIGN(offset) \
        (((offset) + (INT_ALIGNMENT) - 1) & ~((INT_ALIGNMENT) - 1))

/*
 * Macros related to memory allocation
 */

#define MEM_REGION_INIT_MARK       '\0' /* Set this to allocated areas */
#define MEM_REGION_SCRAMBLE_MARK         '\01'  /* Set this to allocated areas */
#define MEM_REGION_GUARD_MARK            '\02'  /* Set this as a memory guard to detect over/under runs */

#if defined (CUBRID_DEBUG)
extern void db_scramble (void *region, int size);
#define MEM_REGION_INIT(region, size) \
        memset((region), MEM_REGION_SCRAMBLE_MARK, (size))
#define MEM_REGION_SCRAMBLE(region, size) \
        memset (region, MEM_REGION_SCRAMBLE_MARK, size)
#else /* CUBRID_DEBUG */
#define MEM_REGION_INIT(region, size) \
        memset((region), MEM_REGION_INIT_MARK, (size))
#define MEM_REGION_SCRAMBLE(region, size)
#endif /* CUBRID_DEBUG */

#if defined(NDEBUG)
#define db_private_free_and_init(thrd, ptr) \
        do { \
          if ((ptr)) { \
            db_private_free ((thrd), (ptr)); \
            (ptr) = NULL; \
          } \
        } while (0)

#define free_and_init(ptr) \
        do { \
          if ((ptr)) { \
            free ((void*) (ptr)); \
            (ptr) = NULL; \
          } \
        } while (0)

#define os_free_and_init(ptr) \
        do { \
          if ((ptr)) { \
            os_free((ptr)); \
            (ptr) = NULL; \
          } \
        } while (0)
#else /* NDEBUG */
#define db_private_free_and_init(thrd, ptr) \
        do { \
          db_private_free ((thrd), (ptr)); \
          (ptr) = NULL; \
    } while (0)

#define free_and_init(ptr) \
        do { \
          free ((void*) (ptr)); \
          (ptr) = NULL; \
    } while (0)

#define os_free_and_init(ptr) \
        do { \
          os_free((ptr)); \
          (ptr) = NULL; \
        } while (0)
#endif /* NDEBUG */

extern int ansisql_strcmp (const char *s, const char *t);
extern int ansisql_strcasecmp (const char *s, const char *t);

#if !defined (SERVER_MODE)

extern HL_HEAPID private_heap_id;

#define os_malloc(size) (malloc (size))
#define os_free(ptr) (free (ptr))
#define os_realloc(ptr, size) (realloc ((ptr), (size)))

#else /* SERVER_MODE */

#if !defined(NDEBUG)
#define os_malloc(size) \
        os_malloc_debug(size, true, __FILE__, __LINE__)
extern void *os_malloc_debug (size_t size, bool rc_track, const char *caller_file, int caller_line);
#define os_calloc(n, size) \
        os_calloc_debug(n, size, true, __FILE__, __LINE__)
extern void *os_calloc_debug (size_t n, size_t size, bool rc_track, const char *caller_file, int caller_line);
#define os_free(ptr) \
        os_free_debug(ptr, true, __FILE__, __LINE__)
extern void os_free_debug (void *ptr, bool rc_track, const char *caller_file, int caller_line);
#define os_realloc(ptr, size) (realloc ((ptr), (size)))
#else /* NDEBUG */
#define os_malloc(size) \
        os_malloc_release(size, false)
extern void *os_malloc_release (size_t size, bool rc_track);
#define os_calloc(n, size) \
        os_calloc_release(n, size, false)
extern void *os_calloc_release (size_t n, size_t size, bool rc_track);
#define os_free(ptr) \
        os_free_release(ptr, false)
extern void os_free_release (void *ptr, bool rc_track);
#define os_realloc(ptr, size) (realloc ((ptr), (size)))
#endif /* NDEBUG */

#endif /* SERVER_MODE */

/*
 * Return the assumed minimum alignment requirement for the requested
 * size.  Multiples of sizeof(double) are assumed to need double
 * alignment, etc.
 */
extern int db_alignment (int);

/*
 * Return the value of "n" to the next "alignment" boundary.  "alignment"
 * must be a power of 2.
 */
extern int db_align_to (int n, int alignment);

extern HL_HEAPID db_create_ostk_heap (int chunk_size);
extern void db_destroy_ostk_heap (HL_HEAPID heap_id);

extern void *db_ostk_alloc (HL_HEAPID heap_id, size_t size);
#if defined(ENABLE_UNUSED_FUNCTION)
extern void db_ostk_free (HL_HEAPID heap_id, void *ptr);
#endif

extern HL_HEAPID db_create_private_heap (void);
extern void db_clear_private_heap (THREAD_ENTRY * thread_p, HL_HEAPID heap_id);
extern HL_HEAPID db_change_private_heap (THREAD_ENTRY * thread_p, HL_HEAPID heap_id);
extern HL_HEAPID db_replace_private_heap (THREAD_ENTRY * thread_p);
extern void db_destroy_private_heap (THREAD_ENTRY * thread_p, HL_HEAPID heap_id);

#if !defined(NDEBUG)
#define db_private_alloc(thrd, size) \
        db_private_alloc_debug(thrd, size, true, __FILE__, __LINE__)
#define db_private_free(thrd, ptr) \
        db_private_free_debug(thrd, ptr, true, __FILE__, __LINE__)
#define db_private_realloc(thrd, ptr, size) \
        db_private_realloc_debug(thrd, ptr, size, true, __FILE__, __LINE__)

#ifdef __cplusplus
extern "C"
{
#endif
  extern void *db_private_alloc_debug (THREAD_ENTRY * thrd, size_t size, bool rc_track, const char *caller_file,
                       int caller_line);
  extern void db_private_free_debug (THREAD_ENTRY * thrd, void *ptr, bool rc_track, const char *caller_file,
                     int caller_line);
  extern void *db_private_realloc_debug (THREAD_ENTRY * thrd, void *ptr, size_t size, bool rc_track,
                     const char *caller_file, int caller_line);
#ifdef __cplusplus
}
#endif

#else /* NDEBUG */
#define db_private_alloc(thrd, size) \
        db_private_alloc_release(thrd, size, false)
#define db_private_free(thrd, ptr) \
        db_private_free_release(thrd, ptr, false)
#define db_private_realloc(thrd, ptr, size) \
        db_private_realloc_release(thrd, ptr, size, false)


#ifdef __cplusplus
extern "C"
{
#endif
  extern void *db_private_alloc_release (THREAD_ENTRY * thrd, size_t size, bool rc_track);
  extern void db_private_free_release (THREAD_ENTRY * thrd, void *ptr, bool rc_track);
  extern void *db_private_realloc_release (THREAD_ENTRY * thrd, void *ptr, size_t size, bool rc_track);
#ifdef __cplusplus
}
#endif
#endif              /* NDEBUG */

#ifdef __cplusplus
extern "C"
{
#endif
  extern char *db_private_strdup (THREAD_ENTRY * thrd, const char *s);
  extern char *db_private_strndup (THREAD_ENTRY * thrd, const char *s, size_t size);
#ifdef __cplusplus
}
#endif

/* for external package */
extern void *db_private_alloc_external (THREAD_ENTRY * thrd, size_t size);
extern void db_private_free_external (THREAD_ENTRY * thrd, void *ptr);
extern void *db_private_realloc_external (THREAD_ENTRY * thrd, void *ptr, size_t size);

#if defined (SERVER_MODE)
extern HL_HEAPID db_private_set_heapid_to_thread (THREAD_ENTRY * thread_p, HL_HEAPID heap_id);
#endif // SERVER_MODE

extern HL_HEAPID db_create_fixed_heap (int req_size, int recs_per_chunk);
extern void db_destroy_fixed_heap (HL_HEAPID heap_id);
extern void *db_fixed_alloc (HL_HEAPID heap_id, size_t size);
extern void db_fixed_free (HL_HEAPID heap_id, void *ptr);

#if defined(SA_MODE)
typedef struct private_malloc_header_s PRIVATE_MALLOC_HEADER;
struct private_malloc_header_s
{
  unsigned int magic;
  int alloc_type;
};

#define PRIVATE_MALLOC_HEADER_MAGIC 0xafdaafdaU

enum
{
  PRIVATE_ALLOC_TYPE_LEA = 1,
  PRIVATE_ALLOC_TYPE_WS = 2
};

#define PRIVATE_MALLOC_HEADER_ALIGNED_SIZE \
  ((sizeof(PRIVATE_MALLOC_HEADER) + 7) & ~7)

#define private_request_size(s) \
  (PRIVATE_MALLOC_HEADER_ALIGNED_SIZE + (s))

#define private_hl2user_ptr(ptr) \
  (void *)((char *)(ptr) + PRIVATE_MALLOC_HEADER_ALIGNED_SIZE)

#define private_user2hl_ptr(ptr) \
  (PRIVATE_MALLOC_HEADER *)((char *)(ptr) - PRIVATE_MALLOC_HEADER_ALIGNED_SIZE)
#endif /* SA_MODE */

#endif /* _MEMORY_ALLOC_H_ */