2007-09-28 17:11:22 +00:00
# ifndef MEMORY_H
# define MEMORY_H
2007-11-29 14:18:54 +00:00
# ident "Copyright (c) 2007 Tokutek Inc. All rights reserved."
2008-01-23 18:35:54 +00:00
# include <stdlib.h>
2013-04-16 23:58:00 -04:00
# include <toku_portability.h>
2007-07-13 19:37:47 +00:00
2013-04-16 23:59:09 -04:00
# if defined(__cplusplus) || defined(__cilkplusplus)
extern " C " {
# endif
2007-08-09 13:26:51 +00:00
/* Tokutek memory allocation functions and macros.
* These are functions for malloc and free */
/* Generally: errno is set to 0 or a value to indicate problems. */
/* Everything should call toku_malloc() instead of malloc(), and toku_calloc() instead of calloc() */
2013-04-16 23:57:33 -04:00
void * toku_calloc ( size_t nmemb , size_t size ) __attribute__ ( ( __visibility__ ( " default " ) ) ) ;
2013-04-16 23:57:47 -04:00
void * toku_xcalloc ( size_t nmemb , size_t size ) __attribute__ ( ( __visibility__ ( " default " ) ) ) ;
2013-04-16 23:57:33 -04:00
void * toku_malloc ( size_t size ) __attribute__ ( ( __visibility__ ( " default " ) ) ) ;
2013-04-16 23:57:18 -04:00
// xmalloc aborts instead of return NULL if we run out of memory
void * toku_xmalloc ( size_t size ) ;
2013-04-16 23:59:01 -04:00
void * toku_xrealloc ( void * , size_t size ) __attribute__ ( ( __visibility__ ( " default " ) ) ) ;
2013-04-16 23:57:18 -04:00
2013-04-16 23:57:33 -04:00
void toku_free ( void * ) __attribute__ ( ( __visibility__ ( " default " ) ) ) ;
2007-08-09 13:26:51 +00:00
/* toku_free_n() should be used if the caller knows the size of the malloc'd object. */
2008-01-23 18:35:54 +00:00
void toku_free_n ( void * , size_t size ) ;
2013-04-16 23:57:33 -04:00
void * toku_realloc ( void * , size_t size ) __attribute__ ( ( __visibility__ ( " default " ) ) ) ;
2007-07-13 19:37:47 +00:00
2007-08-09 13:26:51 +00:00
/* MALLOC is a macro that helps avoid a common error:
* Suppose I write
* struct foo * x = malloc ( sizeof ( struct foo ) ) ;
* That works fine . But if I change it to this , I ' ve probably made an mistake :
* struct foo * x = malloc ( sizeof ( struct bar ) ) ;
* It can get worse , since one might have something like
* struct foo * x = malloc ( sizeof ( struct foo * ) )
* which looks reasonable , but it allocoates enough to hold a pointer instead of the amount needed for the struct .
* So instead , write
* struct foo * MALLOC ( x ) ;
* and you cannot go wrong .
*/
2013-04-16 23:59:09 -04:00
# define MALLOC(v) v = cast_to_typeof(v) toku_malloc(sizeof(*v))
2013-04-16 23:57:47 -04:00
/* MALLOC_N is like calloc(Except no 0ing of data): It makes an array. Write
2007-08-09 13:26:51 +00:00
* int * MALLOC_N ( 5 , x ) ;
* to make an array of 5 integers .
*/
2013-04-16 23:59:09 -04:00
# define MALLOC_N(n,v) v = cast_to_typeof(v) toku_malloc((n)*sizeof(*v))
2007-07-13 19:37:47 +00:00
2013-04-16 23:57:47 -04:00
//CALLOC_N is like calloc with auto-figuring out size of members
2013-04-16 23:59:09 -04:00
# define CALLOC_N(n,v) v = cast_to_typeof(v) toku_calloc((n), sizeof(*v))
2013-04-16 23:57:47 -04:00
# define CALLOC(v) CALLOC_N(1,v)
2013-04-16 23:59:09 -04:00
# define REALLOC_N(n,v) v = cast_to_typeof(v) toku_realloc(v, (n)*sizeof(*v))
2008-03-06 21:46:57 +00:00
2013-04-16 23:57:20 -04:00
// XMALLOC macros are like MALLOC except they abort if the operation fails
2013-04-16 23:59:09 -04:00
# define XMALLOC(v) v = cast_to_typeof(v) toku_xmalloc(sizeof(*v))
# define XMALLOC_N(n,v) v = cast_to_typeof(v) toku_xmalloc((n)*sizeof(*v))
# define XCALLOC_N(n,v) v = cast_to_typeof(v) toku_xcalloc((n), (sizeof(*v)))
2013-04-16 23:57:47 -04:00
# define XCALLOC(v) XCALLOC_N(1,(v))
2013-04-16 23:59:09 -04:00
# define XREALLOC_N(n,v) v = cast_to_typeof(v) toku_xrealloc(v, (n)*sizeof(*v))
2013-04-16 23:57:18 -04:00
2007-08-09 13:26:51 +00:00
/* Copy memory. Analogous to strdup() */
2008-01-23 18:35:54 +00:00
void * toku_memdup ( const void * v , size_t len ) ;
2007-08-09 13:26:51 +00:00
/* Toku-version of strdup. Use this so that it calls toku_malloc() */
2013-04-16 23:57:33 -04:00
char * toku_strdup ( const char * s ) __attribute__ ( ( __visibility__ ( " default " ) ) ) ;
2007-07-13 19:37:47 +00:00
2013-04-16 23:58:04 -04:00
/* Copy memory. Analogous to strdup() Crashes instead of returning NULL */
2013-04-16 23:58:59 -04:00
void * toku_xmemdup ( const void * v , size_t len ) __attribute__ ( ( __visibility__ ( " default " ) ) ) ;
2013-04-16 23:58:04 -04:00
/* Toku-version of strdup. Use this so that it calls toku_xmalloc() Crashes instead of returning NULL */
char * toku_xstrdup ( const char * s ) __attribute__ ( ( __visibility__ ( " default " ) ) ) ;
2007-11-29 15:34:49 +00:00
void toku_malloc_cleanup ( void ) ; /* Before exiting, call this function to free up any internal data structures from toku_malloc. Otherwise valgrind will complain of memory leaks. */
2007-08-09 13:26:51 +00:00
/* Check to see if everything malloc'd was free. Might be a no-op depending on how memory.c is configured. */
2007-11-29 15:34:49 +00:00
void toku_memory_check_all_free ( void ) ;
2007-08-09 13:26:51 +00:00
/* Check to see if memory is "sane". Might be a no-op. Probably better to simply use valgrind. */
2007-11-29 15:41:46 +00:00
void toku_do_memory_check ( void ) ;
2007-07-13 19:37:47 +00:00
2007-11-29 15:34:49 +00:00
extern int toku_memory_check ; // Set to nonzero to get a (much) slower version of malloc that does (much) more checking.
2007-07-13 19:37:47 +00:00
2007-11-29 15:41:46 +00:00
int toku_get_n_items_malloced ( void ) ; /* How many items are malloc'd but not free'd. May return 0 depending on the configuration of memory.c */
2007-11-29 15:34:49 +00:00
void toku_print_malloced_items ( void ) ; /* Try to print some malloced-but-not-freed items. May be a noop. */
2007-11-29 15:41:46 +00:00
void toku_malloc_report ( void ) ; /* report on statistics about number of mallocs. Maybe a no-op. */
2007-08-09 13:26:51 +00:00
2008-04-02 23:40:36 +00:00
// For memory-debug.c Set this to an array of integers that say which mallocs should return NULL and ENOMEM.
// The array is terminated by a -1.
extern int * toku_dead_mallocs ;
extern int toku_malloc_counter ; // so you can reset it
2013-04-16 23:57:31 -04:00
extern int toku_realloc_counter ;
extern int toku_calloc_counter ;
extern int toku_free_counter ;
2008-04-02 23:40:36 +00:00
2013-04-16 23:59:38 -04:00
typedef void * ( * malloc_fun_t ) ( size_t ) ;
typedef void ( * free_fun_t ) ( void * ) ;
typedef void * ( * realloc_fun_t ) ( void * , size_t ) ;
void toku_set_func_malloc ( malloc_fun_t f ) ;
void toku_set_func_xmalloc_only ( malloc_fun_t f ) ;
void toku_set_func_malloc_only ( malloc_fun_t f ) ;
void toku_set_func_realloc ( realloc_fun_t f ) ;
void toku_set_func_xrealloc_only ( realloc_fun_t f ) ;
void toku_set_func_realloc_only ( realloc_fun_t f ) ;
void toku_set_func_free ( free_fun_t f ) ;
2013-04-16 23:59:47 -04:00
typedef struct memory_status {
uint64_t malloc_count ; // number of malloc operations
uint64_t free_count ; // number of free operations
uint64_t realloc_count ; // number of realloc operations
2013-04-16 23:59:47 -04:00
uint64_t malloc_fail ; // number of malloc operations that failed
uint64_t realloc_fail ; // number of realloc operations that failed
2013-04-16 23:59:47 -04:00
uint64_t requested ; // number of bytes requested
uint64_t used ; // number of bytes used (requested + overhead), obtained from malloc_usable_size()
uint64_t freed ; // number of bytes freed;
2013-04-16 23:59:50 -04:00
uint64_t max_in_use ; // maximum memory footprint (used - freed), approximate (not worth threadsafety overhead for exact)
2013-04-16 23:59:47 -04:00
} MEMORY_STATUS_S , * MEMORY_STATUS ;
void toku_memory_get_status ( MEMORY_STATUS s ) ;
2013-04-16 23:59:09 -04:00
# if defined(__cplusplus) || defined(__cilkplusplus)
2013-04-16 23:59:38 -04:00
}
2013-04-16 23:57:34 -04:00
# endif
2007-09-28 17:11:22 +00:00
# endif