2007-09-28 17:11:22 +00:00
# ifndef MEMORY_H
# define MEMORY_H
2013-04-16 23:57:34 -04:00
# if defined __cplusplus
extern " C " {
# endif
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
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. */
2008-04-07 11:25:11 +00:00
enum typ_tag { TYP_BRTNODE = 0xdead0001 ,
2008-04-02 23:40:36 +00:00
TYP_CACHETABLE , TYP_PAIR , /* for cachetables */
TYP_PMA ,
TYP_GPMA ,
TYP_TOKULOGGER ,
2008-04-07 01:30:25 +00:00
TYP_TOKUTXN ,
TYP_LEAFENTRY
2008-04-02 23:40:36 +00:00
} ;
2007-08-09 13:26:51 +00:00
/* 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:57:34 -04:00
void * toku_xrealloc ( void * , size_t size ) ;
2013-04-16 23:57:18 -04:00
2007-11-29 15:34:49 +00:00
/* toku_tagmalloc() performs a malloc(size), but fills in the first 4 bytes with typ.
2007-08-09 13:26:51 +00:00
* This " tag " is useful if you are debugging and run across a void * that is
* really a ( struct foo * ) , and you want to figure out what it is .
*/
2008-04-02 23:40:36 +00:00
void * toku_tagmalloc ( size_t size , enum typ_tag typ ) ;
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 .
*/
2007-07-20 18:00:14 +00:00
# define MALLOC(v) 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 .
*/
2007-07-20 18:00:14 +00:00
# define MALLOC_N(n,v) 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
# define CALLOC_N(n,v) v = toku_calloc((n), sizeof(*v))
# define CALLOC(v) CALLOC_N(1,v)
2008-03-06 21:46:57 +00:00
# define REALLOC_N(n,v) v = toku_realloc(v, (n)*sizeof(*v))
2013-04-16 23:57:20 -04:00
// XMALLOC macros are like MALLOC except they abort if the operation fails
2013-04-16 23:57:18 -04:00
# define XMALLOC(v) v = toku_xmalloc(sizeof(*v))
2013-04-16 23:57:34 -04:00
# define XMALLOC_N(n,v) v = toku_xmalloc((n)*sizeof(*v))
2013-04-16 23:57:47 -04:00
# define XCALLOC_N(n,v) v = toku_xcalloc((n), (sizeof(*v)))
# define XCALLOC(v) XCALLOC_N(1,(v))
2013-04-16 23:57:34 -04:00
# define XREALLOC_N(n,v) v = toku_xrealloc(v, (n)*sizeof(*v))
2013-04-16 23:57:18 -04:00
2007-08-09 13:26:51 +00:00
/* If you have a type such as
* struct pma * PMA ;
* and you define a corresponding int constant , such as
* enum typ_tag { TYP_PMA } ;
* then if you do
* TAGMALLOC ( PMA , v ) ;
* you declare a variable v of type PMA and malloc a struct pma , and fill
2007-11-29 15:34:49 +00:00
* in that " tag " with toku_tagmalloc ( ) .
2007-08-09 13:26:51 +00:00
*/
2007-11-29 15:34:49 +00:00
# define TAGMALLOC(t,v) t v = toku_tagmalloc(sizeof(*v), TYP_ ## t);
2007-07-13 19:37:47 +00: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
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:57:34 -04:00
# if defined __cplusplus
} ;
# endif
2007-09-28 17:11:22 +00:00
# endif