]>
Commit | Line | Data |
---|---|---|
494da23a TL |
1 | // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. |
2 | // This source code is licensed under both the GPLv2 (found in the | |
3 | // COPYING file in the root directory) and Apache 2.0 License | |
4 | // (found in the LICENSE.Apache file in the root directory). | |
5 | ||
6 | #pragma once | |
7 | ||
1e59de90 | 8 | #if defined(__clang__) && defined(__GLIBC__) |
f67539c2 TL |
9 | // glibc's `posix_memalign()` declaration specifies `throw()` while clang's |
10 | // declaration does not. There is a hack in clang to make its re-declaration | |
11 | // compatible with glibc's if they are declared consecutively. That hack breaks | |
12 | // if yet another `posix_memalign()` declaration comes between glibc's and | |
13 | // clang's declarations. Include "mm_malloc.h" here ensures glibc's and clang's | |
14 | // declarations both come before "jemalloc.h"'s `posix_memalign()` declaration. | |
15 | // | |
16 | // This problem could also be avoided if "jemalloc.h"'s `posix_memalign()` | |
17 | // declaration did not specify `throw()` when built with clang. | |
18 | #include <mm_malloc.h> | |
19 | #endif | |
20 | ||
494da23a TL |
21 | #ifdef ROCKSDB_JEMALLOC |
22 | #ifdef __FreeBSD__ | |
23 | #include <malloc_np.h> | |
1e59de90 | 24 | #define JEMALLOC_USABLE_SIZE_CONST const |
494da23a | 25 | #else |
f67539c2 | 26 | #define JEMALLOC_MANGLE |
494da23a TL |
27 | #include <jemalloc/jemalloc.h> |
28 | #endif | |
29 | ||
30 | #ifndef JEMALLOC_CXX_THROW | |
31 | #define JEMALLOC_CXX_THROW | |
32 | #endif | |
33 | ||
f67539c2 TL |
34 | #if defined(OS_WIN) && defined(_MSC_VER) |
35 | ||
36 | // MSVC does not have weak symbol support. As long as ROCKSDB_JEMALLOC is | |
37 | // defined, Jemalloc memory allocator is used. | |
38 | static inline bool HasJemalloc() { return true; } | |
39 | ||
40 | #else | |
41 | ||
20effc67 TL |
42 | // definitions for compatibility with older versions of jemalloc |
43 | #if !defined(JEMALLOC_ALLOCATOR) | |
44 | #define JEMALLOC_ALLOCATOR | |
45 | #endif | |
46 | #if !defined(JEMALLOC_RESTRICT_RETURN) | |
47 | #define JEMALLOC_RESTRICT_RETURN | |
48 | #endif | |
49 | #if !defined(JEMALLOC_NOTHROW) | |
50 | #define JEMALLOC_NOTHROW JEMALLOC_ATTR(nothrow) | |
51 | #endif | |
52 | #if !defined(JEMALLOC_ALLOC_SIZE) | |
53 | #ifdef JEMALLOC_HAVE_ATTR_ALLOC_SIZE | |
54 | #define JEMALLOC_ALLOC_SIZE(s) JEMALLOC_ATTR(alloc_size(s)) | |
55 | #else | |
56 | #define JEMALLOC_ALLOC_SIZE(s) | |
57 | #endif | |
58 | #endif | |
59 | ||
494da23a TL |
60 | // Declare non-standard jemalloc APIs as weak symbols. We can null-check these |
61 | // symbols to detect whether jemalloc is linked with the binary. | |
20effc67 TL |
62 | extern "C" JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN void JEMALLOC_NOTHROW * |
63 | mallocx(size_t, int) JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(1) | |
64 | __attribute__((__weak__)); | |
65 | extern "C" JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN void JEMALLOC_NOTHROW * | |
66 | rallocx(void *, size_t, int) JEMALLOC_ALLOC_SIZE(2) __attribute__((__weak__)); | |
67 | extern "C" size_t JEMALLOC_NOTHROW xallocx(void *, size_t, size_t, int) | |
68 | __attribute__((__weak__)); | |
69 | extern "C" size_t JEMALLOC_NOTHROW sallocx(const void *, int) | |
70 | JEMALLOC_ATTR(pure) __attribute__((__weak__)); | |
71 | extern "C" void JEMALLOC_NOTHROW dallocx(void *, int) __attribute__((__weak__)); | |
72 | extern "C" void JEMALLOC_NOTHROW sdallocx(void *, size_t, int) | |
73 | __attribute__((__weak__)); | |
74 | extern "C" size_t JEMALLOC_NOTHROW nallocx(size_t, int) JEMALLOC_ATTR(pure) | |
75 | __attribute__((__weak__)); | |
76 | extern "C" int JEMALLOC_NOTHROW mallctl(const char *, void *, size_t *, void *, | |
77 | size_t) __attribute__((__weak__)); | |
78 | extern "C" int JEMALLOC_NOTHROW mallctlnametomib(const char *, size_t *, | |
79 | size_t *) | |
80 | __attribute__((__weak__)); | |
81 | extern "C" int JEMALLOC_NOTHROW mallctlbymib(const size_t *, size_t, void *, | |
82 | size_t *, void *, size_t) | |
83 | __attribute__((__weak__)); | |
84 | extern "C" void JEMALLOC_NOTHROW | |
85 | malloc_stats_print(void (*)(void *, const char *), void *, const char *) | |
494da23a | 86 | __attribute__((__weak__)); |
20effc67 TL |
87 | extern "C" size_t JEMALLOC_NOTHROW |
88 | malloc_usable_size(JEMALLOC_USABLE_SIZE_CONST void *) JEMALLOC_CXX_THROW | |
494da23a | 89 | __attribute__((__weak__)); |
494da23a TL |
90 | |
91 | // Check if Jemalloc is linked with the binary. Note the main program might be | |
92 | // using a different memory allocator even this method return true. | |
93 | // It is loosely based on folly::usingJEMalloc(), minus the check that actually | |
94 | // allocate memory and see if it is through jemalloc, to handle the dlopen() | |
95 | // case: | |
96 | // https://github.com/facebook/folly/blob/76cf8b5841fb33137cfbf8b224f0226437c855bc/folly/memory/Malloc.h#L147 | |
97 | static inline bool HasJemalloc() { | |
98 | return mallocx != nullptr && rallocx != nullptr && xallocx != nullptr && | |
99 | sallocx != nullptr && dallocx != nullptr && sdallocx != nullptr && | |
100 | nallocx != nullptr && mallctl != nullptr && | |
101 | mallctlnametomib != nullptr && mallctlbymib != nullptr && | |
102 | malloc_stats_print != nullptr && malloc_usable_size != nullptr; | |
103 | } | |
104 | ||
f67539c2 TL |
105 | #endif |
106 | ||
494da23a | 107 | #endif // ROCKSDB_JEMALLOC |