1/* zmalloc - total amount of allocated memory aware version of malloc()
2 *
3 * Copyright (c) 2009-2010, Salvatore Sanfilippo <antirez at gmail dot com>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * * Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * * Neither the name of Redis nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without
16 * specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#ifndef __ZMALLOC_H
32#define __ZMALLOC_H
33
34/* Double expansion needed for stringification of macro values. */
35#define __xstr(s) __str(s)
36#define __str(s) #s
37
38#if defined(USE_TCMALLOC)
39#define ZMALLOC_LIB ("tcmalloc-" __xstr(TC_VERSION_MAJOR) "." __xstr(TC_VERSION_MINOR))
40#include <google/tcmalloc.h>
41#if (TC_VERSION_MAJOR == 1 && TC_VERSION_MINOR >= 6) || (TC_VERSION_MAJOR > 1)
42#define HAVE_MALLOC_SIZE 1
43#define zmalloc_size(p) tc_malloc_size(p)
44#else
45#error "Newer version of tcmalloc required"
46#endif
47
48#elif defined(USE_JEMALLOC)
49#define ZMALLOC_LIB ("jemalloc-" __xstr(JEMALLOC_VERSION_MAJOR) "." __xstr(JEMALLOC_VERSION_MINOR) "." __xstr(JEMALLOC_VERSION_BUGFIX))
50#include <jemalloc/jemalloc.h>
51#if (JEMALLOC_VERSION_MAJOR == 2 && JEMALLOC_VERSION_MINOR >= 1) || (JEMALLOC_VERSION_MAJOR > 2)
52#define HAVE_MALLOC_SIZE 1
53#define zmalloc_size(p) je_malloc_usable_size(p)
54#else
55#error "Newer version of jemalloc required"
56#endif
57
58#elif defined(__APPLE__)
59#include <malloc/malloc.h>
60#define HAVE_MALLOC_SIZE 1
61#define zmalloc_size(p) malloc_size(p)
62#endif
63
64/* On native libc implementations, we should still do our best to provide a
65 * HAVE_MALLOC_SIZE capability. This can be set explicitly as well:
66 *
67 * NO_MALLOC_USABLE_SIZE disables it on all platforms, even if they are
68 * known to support it.
69 * USE_MALLOC_USABLE_SIZE forces use of malloc_usable_size() regardless
70 * of platform.
71 */
72#ifndef ZMALLOC_LIB
73#define ZMALLOC_LIB "libc"
74
75#if !defined(NO_MALLOC_USABLE_SIZE) && \
76 (defined(__GLIBC__) || defined(__FreeBSD__) || \
77 defined(USE_MALLOC_USABLE_SIZE))
78
79/* Includes for malloc_usable_size() */
80#ifdef __FreeBSD__
81#include <malloc_np.h>
82#else
83#include <malloc.h>
84#endif
85
86#define HAVE_MALLOC_SIZE 1
87#define zmalloc_size(p) malloc_usable_size(p)
88
89#endif
90#endif
91
92/* We can enable the Redis defrag capabilities only if we are using Jemalloc
93 * and the version used is our special version modified for Redis having
94 * the ability to return per-allocation fragmentation hints. */
95#if defined(USE_JEMALLOC) && defined(JEMALLOC_FRAG_HINT)
96#define HAVE_DEFRAG
97#endif
98
99void *zmalloc(size_t size);
100void *zcalloc(size_t size);
101void *zcalloc_num(size_t num, size_t size);
102void *zrealloc(void *ptr, size_t size);
103void *ztrymalloc(size_t size);
104void *ztrycalloc(size_t size);
105void *ztryrealloc(void *ptr, size_t size);
106void zfree(void *ptr);
107void *zmalloc_usable(size_t size, size_t *usable);
108void *zcalloc_usable(size_t size, size_t *usable);
109void *zrealloc_usable(void *ptr, size_t size, size_t *usable);
110void *ztrymalloc_usable(size_t size, size_t *usable);
111void *ztrycalloc_usable(size_t size, size_t *usable);
112void *ztryrealloc_usable(void *ptr, size_t size, size_t *usable);
113void zfree_usable(void *ptr, size_t *usable);
114char *zstrdup(const char *s);
115size_t zmalloc_used_memory(void);
116void zmalloc_set_oom_handler(void (*oom_handler)(size_t));
117size_t zmalloc_get_rss(void);
118int zmalloc_get_allocator_info(size_t *allocated, size_t *active, size_t *resident);
119void set_jemalloc_bg_thread(int enable);
120int jemalloc_purge();
121size_t zmalloc_get_private_dirty(long pid);
122size_t zmalloc_get_smap_bytes_by_field(char *field, long pid);
123size_t zmalloc_get_memory_size(void);
124void zlibc_free(void *ptr);
125void zmadvise_dontneed(void *ptr);
126
127#ifdef HAVE_DEFRAG
128void zfree_no_tcache(void *ptr);
129void *zmalloc_no_tcache(size_t size);
130#endif
131
132#ifndef HAVE_MALLOC_SIZE
133size_t zmalloc_size(void *ptr);
134size_t zmalloc_usable_size(void *ptr);
135#else
136#define zmalloc_usable_size(p) zmalloc_size(p)
137#endif
138
139int get_proc_stat_ll(int i, long long *res);
140
141#ifdef REDIS_TEST
142int zmalloc_test(int argc, char **argv, int flags);
143#endif
144
145#endif /* __ZMALLOC_H */
146