Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
f63e81c2
Unverified
Commit
f63e81c2
authored
Aug 25, 2018
by
Chris Lamb
Committed by
GitHub
Aug 25, 2018
Browse files
Merge branch 'unstable' into config-set-maxmemory-grammar
parents
eaeba1b2
39c70e72
Changes
209
Show whitespace changes
Inline
Side-by-side
Too many changes to show.
To preserve performance only
209 of 209+
files are displayed.
Plain diff
Email patch
deps/jemalloc/include/jemalloc/internal/ticker.h
0 → 100644
View file @
f63e81c2
#ifndef JEMALLOC_INTERNAL_TICKER_H
#define JEMALLOC_INTERNAL_TICKER_H
#include "jemalloc/internal/util.h"
/**
* A ticker makes it easy to count-down events until some limit. You
* ticker_init the ticker to trigger every nticks events. You then notify it
* that an event has occurred with calls to ticker_tick (or that nticks events
* have occurred with a call to ticker_ticks), which will return true (and reset
* the counter) if the countdown hit zero.
*/
typedef
struct
{
int32_t
tick
;
int32_t
nticks
;
}
ticker_t
;
static
inline
void
ticker_init
(
ticker_t
*
ticker
,
int32_t
nticks
)
{
ticker
->
tick
=
nticks
;
ticker
->
nticks
=
nticks
;
}
static
inline
void
ticker_copy
(
ticker_t
*
ticker
,
const
ticker_t
*
other
)
{
*
ticker
=
*
other
;
}
static
inline
int32_t
ticker_read
(
const
ticker_t
*
ticker
)
{
return
ticker
->
tick
;
}
/*
* Not intended to be a public API. Unfortunately, on x86, neither gcc nor
* clang seems smart enough to turn
* ticker->tick -= nticks;
* if (unlikely(ticker->tick < 0)) {
* fixup ticker
* return true;
* }
* return false;
* into
* subq %nticks_reg, (%ticker_reg)
* js fixup ticker
*
* unless we force "fixup ticker" out of line. In that case, gcc gets it right,
* but clang now does worse than before. So, on x86 with gcc, we force it out
* of line, but otherwise let the inlining occur. Ordinarily this wouldn't be
* worth the hassle, but this is on the fast path of both malloc and free (via
* tcache_event).
*/
#if defined(__GNUC__) && !defined(__clang__) \
&& (defined(__x86_64__) || defined(__i386__))
JEMALLOC_NOINLINE
#endif
static
bool
ticker_fixup
(
ticker_t
*
ticker
)
{
ticker
->
tick
=
ticker
->
nticks
;
return
true
;
}
static
inline
bool
ticker_ticks
(
ticker_t
*
ticker
,
int32_t
nticks
)
{
ticker
->
tick
-=
nticks
;
if
(
unlikely
(
ticker
->
tick
<
0
))
{
return
ticker_fixup
(
ticker
);
}
return
false
;
}
static
inline
bool
ticker_tick
(
ticker_t
*
ticker
)
{
return
ticker_ticks
(
ticker
,
1
);
}
#endif
/* JEMALLOC_INTERNAL_TICKER_H */
deps/jemalloc/include/jemalloc/internal/tsd.h
View file @
f63e81c2
/******************************************************************************/
#
if
def JEMALLOC_
H_TYPES
#ifndef JEMALLOC_INTERNAL_TSD_H
#def
ine
JEMALLOC_
INTERNAL_TSD_H
/* Maximum number of malloc_tsd users with cleanup functions. */
#define MALLOC_TSD_CLEANUPS_MAX 8
#include "jemalloc/internal/arena_types.h"
#include "jemalloc/internal/assert.h"
#include "jemalloc/internal/jemalloc_internal_externs.h"
#include "jemalloc/internal/prof_types.h"
#include "jemalloc/internal/ql.h"
#include "jemalloc/internal/rtree_tsd.h"
#include "jemalloc/internal/tcache_types.h"
#include "jemalloc/internal/tcache_structs.h"
#include "jemalloc/internal/util.h"
#include "jemalloc/internal/witness.h"
typedef
bool
(
*
malloc_tsd_cleanup_t
)(
void
);
#if (!defined(JEMALLOC_MALLOC_THREAD_CLEANUP) && !defined(JEMALLOC_TLS) && \
!defined(_WIN32))
typedef
struct
tsd_init_block_s
tsd_init_block_t
;
typedef
struct
tsd_init_head_s
tsd_init_head_t
;
/*
* Thread-Specific-Data layout
* --- data accessed on tcache fast path: state, rtree_ctx, stats, prof ---
* s: state
* e: tcache_enabled
* m: thread_allocated (config_stats)
* f: thread_deallocated (config_stats)
* p: prof_tdata (config_prof)
* c: rtree_ctx (rtree cache accessed on deallocation)
* t: tcache
* --- data not accessed on tcache fast path: arena-related fields ---
* d: arenas_tdata_bypass
* r: reentrancy_level
* x: narenas_tdata
* i: iarena
* a: arena
* o: arenas_tdata
* Loading TSD data is on the critical path of basically all malloc operations.
* In particular, tcache and rtree_ctx rely on hot CPU cache to be effective.
* Use a compact layout to reduce cache footprint.
* +--- 64-bit and 64B cacheline; 1B each letter; First byte on the left. ---+
* |---------------------------- 1st cacheline ----------------------------|
* | sedrxxxx mmmmmmmm ffffffff pppppppp [c * 32 ........ ........ .......] |
* |---------------------------- 2nd cacheline ----------------------------|
* | [c * 64 ........ ........ ........ ........ ........ ........ .......] |
* |---------------------------- 3nd cacheline ----------------------------|
* | [c * 32 ........ ........ .......] iiiiiiii aaaaaaaa oooooooo [t...... |
* +-------------------------------------------------------------------------+
* Note: the entire tcache is embedded into TSD and spans multiple cachelines.
*
* The last 3 members (i, a and o) before tcache isn't really needed on tcache
* fast path. However we have a number of unused tcache bins and witnesses
* (never touched unless config_debug) at the end of tcache, so we place them
* there to avoid breaking the cachelines and possibly paging in an extra page.
*/
#ifdef JEMALLOC_JET
typedef
void
(
*
test_callback_t
)(
int
*
);
# define MALLOC_TSD_TEST_DATA_INIT 0x72b65c10
# define MALLOC_TEST_TSD \
O(test_data, int, int) \
O(test_callback, test_callback_t, int)
# define MALLOC_TEST_TSD_INITIALIZER , MALLOC_TSD_TEST_DATA_INIT, NULL
#else
# define MALLOC_TEST_TSD
# define MALLOC_TEST_TSD_INITIALIZER
#endif
/* O(name, type, nullable type */
#define MALLOC_TSD \
O(tcache_enabled, bool, bool) \
O(arenas_tdata_bypass, bool, bool) \
O(reentrancy_level, int8_t, int8_t) \
O(narenas_tdata, uint32_t, uint32_t) \
O(offset_state, uint64_t, uint64_t) \
O(thread_allocated, uint64_t, uint64_t) \
O(thread_deallocated, uint64_t, uint64_t) \
O(prof_tdata, prof_tdata_t *, prof_tdata_t *) \
O(rtree_ctx, rtree_ctx_t, rtree_ctx_t) \
O(iarena, arena_t *, arena_t *) \
O(arena, arena_t *, arena_t *) \
O(arenas_tdata, arena_tdata_t *, arena_tdata_t *)\
O(tcache, tcache_t, tcache_t) \
O(witness_tsd, witness_tsd_t, witness_tsdn_t) \
MALLOC_TEST_TSD
#define TSD_INITIALIZER { \
tsd_state_uninitialized, \
TCACHE_ENABLED_ZERO_INITIALIZER, \
false, \
0, \
0, \
0, \
0, \
0, \
NULL, \
RTREE_CTX_ZERO_INITIALIZER, \
NULL, \
NULL, \
NULL, \
TCACHE_ZERO_INITIALIZER, \
WITNESS_TSD_INITIALIZER \
MALLOC_TEST_TSD_INITIALIZER \
}
enum
{
tsd_state_nominal
=
0
,
/* Common case --> jnz. */
tsd_state_nominal_slow
=
1
,
/* Initialized but on slow path. */
/* the above 2 nominal states should be lower values. */
tsd_state_nominal_max
=
1
,
/* used for comparison only. */
tsd_state_minimal_initialized
=
2
,
tsd_state_purgatory
=
3
,
tsd_state_reincarnated
=
4
,
tsd_state_uninitialized
=
5
};
/* Manually limit tsd_state_t to a single byte. */
typedef
uint8_t
tsd_state_t
;
/* The actual tsd. */
struct
tsd_s
{
/*
* The contents should be treated as totally opaque outside the tsd
* module. Access any thread-local state through the getters and
* setters below.
*/
tsd_state_t
state
;
#define O(n, t, nt) \
t use_a_getter_or_setter_instead_##n;
MALLOC_TSD
#undef O
};
/*
* TLS/TSD-agnostic macro-based implementation of thread-specific data. There
* are four macros that support (at least) three use cases: file-private,
* library-private, and library-private inlined. Following is an example
* library-private tsd variable:
*
* In example.h:
* typedef struct {
* int x;
* int y;
* } example_t;
* #define EX_INITIALIZER JEMALLOC_CONCAT({0, 0})
* malloc_tsd_protos(, example, example_t *)
* malloc_tsd_externs(example, example_t *)
* In example.c:
* malloc_tsd_data(, example, example_t *, EX_INITIALIZER)
* malloc_tsd_funcs(, example, example_t *, EX_INITIALIZER,
* example_tsd_cleanup)
*
* The result is a set of generated functions, e.g.:
*
* bool example_tsd_boot(void) {...}
* example_t **example_tsd_get() {...}
* void example_tsd_set(example_t **val) {...}
*
* Note that all of the functions deal in terms of (a_type *) rather than
* (a_type) so that it is possible to support non-pointer types (unlike
* pthreads TSD). example_tsd_cleanup() is passed an (a_type *) pointer that is
* cast to (void *). This means that the cleanup function needs to cast *and*
* dereference the function argument, e.g.:
*
* void
* example_tsd_cleanup(void *arg)
* {
* example_t *example = *(example_t **)arg;
*
* [...]
* if ([want the cleanup function to be called again]) {
* example_tsd_set(&example);
* }
* }
*
* If example_tsd_set() is called within example_tsd_cleanup(), it will be
* called again. This is similar to how pthreads TSD destruction works, except
* that pthreads only calls the cleanup function again if the value was set to
* non-NULL.
* Wrapper around tsd_t that makes it possible to avoid implicit conversion
* between tsd_t and tsdn_t, where tsdn_t is "nullable" and has to be
* explicitly converted to tsd_t, which is non-nullable.
*/
struct
tsdn_s
{
tsd_t
tsd
;
};
#define TSDN_NULL ((tsdn_t *)0)
JEMALLOC_ALWAYS_INLINE
tsdn_t
*
tsd_tsdn
(
tsd_t
*
tsd
)
{
return
(
tsdn_t
*
)
tsd
;
}
JEMALLOC_ALWAYS_INLINE
bool
tsdn_null
(
const
tsdn_t
*
tsdn
)
{
return
tsdn
==
NULL
;
}
/* malloc_tsd_protos(). */
#define malloc_tsd_protos(a_attr, a_name, a_type) \
a_attr bool \
a_name##_tsd_boot(void); \
a_attr a_type * \
a_name##_tsd_get(void); \
a_attr void \
a_name##_tsd_set(a_type *val);
JEMALLOC_ALWAYS_INLINE
tsd_t
*
tsdn_tsd
(
tsdn_t
*
tsdn
)
{
assert
(
!
tsdn_null
(
tsdn
));
/* malloc_tsd_externs(). */
#ifdef JEMALLOC_MALLOC_THREAD_CLEANUP
#define malloc_tsd_externs(a_name, a_type) \
extern __thread a_type a_name##_tls; \
extern __thread bool a_name##_initialized; \
extern bool a_name##_booted;
#elif (defined(JEMALLOC_TLS))
#define malloc_tsd_externs(a_name, a_type) \
extern __thread a_type a_name##_tls; \
extern pthread_key_t a_name##_tsd; \
extern bool a_name##_booted;
#elif (defined(_WIN32))
#define malloc_tsd_externs(a_name, a_type) \
extern DWORD a_name##_tsd; \
extern bool a_name##_booted;
#else
#define malloc_tsd_externs(a_name, a_type) \
extern pthread_key_t a_name##_tsd; \
extern tsd_init_head_t a_name##_tsd_init_head; \
extern bool a_name##_booted;
#endif
return
&
tsdn
->
tsd
;
}
void
*
malloc_tsd_malloc
(
size_t
size
);
void
malloc_tsd_dalloc
(
void
*
wrapper
);
void
malloc_tsd_cleanup_register
(
bool
(
*
f
)(
void
));
tsd_t
*
malloc_tsd_boot0
(
void
);
void
malloc_tsd_boot1
(
void
);
void
tsd_cleanup
(
void
*
arg
);
tsd_t
*
tsd_fetch_slow
(
tsd_t
*
tsd
,
bool
internal
);
void
tsd_slow_update
(
tsd_t
*
tsd
);
/* malloc_tsd_data(). */
/*
* We put the platform-specific data declarations and inlines into their own
* header files to avoid cluttering this file. They define tsd_boot0,
* tsd_boot1, tsd_boot, tsd_booted_get, tsd_get_allocates, tsd_get, and tsd_set.
*/
#ifdef JEMALLOC_MALLOC_THREAD_CLEANUP
#define malloc_tsd_data(a_attr, a_name, a_type, a_initializer) \
a_attr __thread a_type JEMALLOC_TLS_MODEL \
a_name##_tls = a_initializer; \
a_attr __thread bool JEMALLOC_TLS_MODEL \
a_name##_initialized = false; \
a_attr bool a_name##_booted = false;
#include "jemalloc/internal/tsd_malloc_thread_cleanup.h"
#elif (defined(JEMALLOC_TLS))
#define malloc_tsd_data(a_attr, a_name, a_type, a_initializer) \
a_attr __thread a_type JEMALLOC_TLS_MODEL \
a_name##_tls = a_initializer; \
a_attr pthread_key_t a_name##_tsd; \
a_attr bool a_name##_booted = false;
#include "jemalloc/internal/tsd_tls.h"
#elif (defined(_WIN32))
#define malloc_tsd_data(a_attr, a_name, a_type, a_initializer) \
a_attr DWORD a_name##_tsd; \
a_attr bool a_name##_booted = false;
#include "jemalloc/internal/tsd_win.h"
#else
#define malloc_tsd_data(a_attr, a_name, a_type, a_initializer) \
a_attr pthread_key_t a_name##_tsd; \
a_attr tsd_init_head_t a_name##_tsd_init_head = { \
ql_head_initializer(blocks), \
MALLOC_MUTEX_INITIALIZER \
}; \
a_attr bool a_name##_booted = false;
#include "jemalloc/internal/tsd_generic.h"
#endif
/* malloc_tsd_funcs(). */
#ifdef JEMALLOC_MALLOC_THREAD_CLEANUP
#define malloc_tsd_funcs(a_attr, a_name, a_type, a_initializer, \
a_cleanup) \
/* Initialization/cleanup. */
\
a_attr bool \
a_name##_tsd_cleanup_wrapper(void) \
{ \
\
if (a_name##_initialized) { \
a_name##_initialized = false; \
a_cleanup(&a_name##_tls); \
} \
return (a_name##_initialized); \
} \
a_attr bool \
a_name##_tsd_boot(void) \
{ \
\
if (a_cleanup != malloc_tsd_no_cleanup) { \
malloc_tsd_cleanup_register( \
&a_name##_tsd_cleanup_wrapper); \
} \
a_name##_booted = true; \
return (false); \
} \
/* Get/set. */
\
a_attr a_type * \
a_name##_tsd_get(void) \
{ \
\
assert(a_name##_booted); \
return (&a_name##_tls); \
} \
a_attr void \
a_name##_tsd_set(a_type *val) \
{ \
\
assert(a_name##_booted); \
a_name##_tls = (*val); \
if (a_cleanup != malloc_tsd_no_cleanup) \
a_name##_initialized = true; \
/*
* tsd_foop_get_unsafe(tsd) returns a pointer to the thread-local instance of
* foo. This omits some safety checks, and so can be used during tsd
* initialization and cleanup.
*/
#define O(n, t, nt) \
JEMALLOC_ALWAYS_INLINE t * \
tsd_##n##p_get_unsafe(tsd_t *tsd) { \
return &tsd->use_a_getter_or_setter_instead_##n; \
}
#elif (defined(JEMALLOC_TLS))
#define malloc_tsd_funcs(a_attr, a_name, a_type, a_initializer, \
a_cleanup) \
/* Initialization/cleanup. */
\
a_attr bool \
a_name##_tsd_boot(void) \
{ \
\
if (a_cleanup != malloc_tsd_no_cleanup) { \
if (pthread_key_create(&a_name##_tsd, a_cleanup) != 0) \
return (true); \
} \
a_name##_booted = true; \
return (false); \
} \
/* Get/set. */
\
a_attr a_type * \
a_name##_tsd_get(void) \
{ \
\
assert(a_name##_booted); \
return (&a_name##_tls); \
} \
a_attr void \
a_name##_tsd_set(a_type *val) \
{ \
\
assert(a_name##_booted); \
a_name##_tls = (*val); \
if (a_cleanup != malloc_tsd_no_cleanup) { \
if (pthread_setspecific(a_name##_tsd, \
(void *)(&a_name##_tls))) { \
malloc_write("<jemalloc>: Error" \
" setting TSD for "#a_name"\n"); \
if (opt_abort) \
abort(); \
} \
} \
MALLOC_TSD
#undef O
/* tsd_foop_get(tsd) returns a pointer to the thread-local instance of foo. */
#define O(n, t, nt) \
JEMALLOC_ALWAYS_INLINE t * \
tsd_##n##p_get(tsd_t *tsd) { \
assert(tsd->state == tsd_state_nominal || \
tsd->state == tsd_state_nominal_slow || \
tsd->state == tsd_state_reincarnated || \
tsd->state == tsd_state_minimal_initialized); \
return tsd_##n##p_get_unsafe(tsd); \
}
#elif (defined(_WIN32))
#define malloc_tsd_funcs(a_attr, a_name, a_type, a_initializer, \
a_cleanup) \
/* Data structure. */
\
typedef struct { \
bool initialized; \
a_type val; \
} a_name##_tsd_wrapper_t; \
/* Initialization/cleanup. */
\
a_attr bool \
a_name##_tsd_cleanup_wrapper(void) \
{ \
a_name##_tsd_wrapper_t *wrapper; \
\
wrapper = (a_name##_tsd_wrapper_t *) TlsGetValue(a_name##_tsd); \
if (wrapper == NULL) \
return (false); \
if (a_cleanup != malloc_tsd_no_cleanup && \
wrapper->initialized) { \
a_type val = wrapper->val; \
a_type tsd_static_data = a_initializer; \
wrapper->initialized = false; \
wrapper->val = tsd_static_data; \
a_cleanup(&val); \
if (wrapper->initialized) { \
/* Trigger another cleanup round. */
\
return (true); \
} \
} \
malloc_tsd_dalloc(wrapper); \
return (false); \
} \
a_attr bool \
a_name##_tsd_boot(void) \
{ \
\
a_name##_tsd = TlsAlloc(); \
if (a_name##_tsd == TLS_OUT_OF_INDEXES) \
return (true); \
if (a_cleanup != malloc_tsd_no_cleanup) { \
malloc_tsd_cleanup_register( \
&a_name##_tsd_cleanup_wrapper); \
} \
a_name##_booted = true; \
return (false); \
} \
/* Get/set. */
\
a_attr a_name##_tsd_wrapper_t * \
a_name##_tsd_get_wrapper(void) \
{ \
a_name##_tsd_wrapper_t *wrapper = (a_name##_tsd_wrapper_t *) \
TlsGetValue(a_name##_tsd); \
\
if (wrapper == NULL) { \
wrapper = (a_name##_tsd_wrapper_t *) \
malloc_tsd_malloc(sizeof(a_name##_tsd_wrapper_t)); \
if (wrapper == NULL) { \
malloc_write("<jemalloc>: Error allocating" \
" TSD for "#a_name"\n"); \
abort(); \
} else { \
static a_type tsd_static_data = a_initializer; \
wrapper->initialized = false; \
wrapper->val = tsd_static_data; \
} \
if (!TlsSetValue(a_name##_tsd, (void *)wrapper)) { \
malloc_write("<jemalloc>: Error setting" \
" TSD for "#a_name"\n"); \
abort(); \
} \
MALLOC_TSD
#undef O
/*
* tsdn_foop_get(tsdn) returns either the thread-local instance of foo (if tsdn
* isn't NULL), or NULL (if tsdn is NULL), cast to the nullable pointer type.
*/
#define O(n, t, nt) \
JEMALLOC_ALWAYS_INLINE nt * \
tsdn_##n##p_get(tsdn_t *tsdn) { \
if (tsdn_null(tsdn)) { \
return NULL; \
} \
return (wrapper); \
} \
a_attr a_type * \
a_name##_tsd_get(void) \
{ \
a_name##_tsd_wrapper_t *wrapper; \
\
assert(a_name##_booted); \
wrapper = a_name##_tsd_get_wrapper(); \
return (&wrapper->val); \
} \
a_attr void \
a_name##_tsd_set(a_type *val) \
{ \
a_name##_tsd_wrapper_t *wrapper; \
\
assert(a_name##_booted); \
wrapper = a_name##_tsd_get_wrapper(); \
wrapper->val = *(val); \
if (a_cleanup != malloc_tsd_no_cleanup) \
wrapper->initialized = true; \
tsd_t *tsd = tsdn_tsd(tsdn); \
return (nt *)tsd_##n##p_get(tsd); \
}
#else
#define malloc_tsd_funcs(a_attr, a_name, a_type, a_initializer, \
a_cleanup) \
/* Data structure. */
\
typedef struct { \
bool initialized; \
a_type val; \
} a_name##_tsd_wrapper_t; \
/* Initialization/cleanup. */
\
a_attr void \
a_name##_tsd_cleanup_wrapper(void *arg) \
{ \
a_name##_tsd_wrapper_t *wrapper = (a_name##_tsd_wrapper_t *)arg;\
\
if (a_cleanup != malloc_tsd_no_cleanup && \
wrapper->initialized) { \
wrapper->initialized = false; \
a_cleanup(&wrapper->val); \
if (wrapper->initialized) { \
/* Trigger another cleanup round. */
\
if (pthread_setspecific(a_name##_tsd, \
(void *)wrapper)) { \
malloc_write("<jemalloc>: Error" \
" setting TSD for "#a_name"\n"); \
if (opt_abort) \
abort(); \
} \
return; \
} \
} \
malloc_tsd_dalloc(wrapper); \
} \
a_attr bool \
a_name##_tsd_boot(void) \
{ \
\
if (pthread_key_create(&a_name##_tsd, \
a_name##_tsd_cleanup_wrapper) != 0) \
return (true); \
a_name##_booted = true; \
return (false); \
} \
/* Get/set. */
\
a_attr a_name##_tsd_wrapper_t * \
a_name##_tsd_get_wrapper(void) \
{ \
a_name##_tsd_wrapper_t *wrapper = (a_name##_tsd_wrapper_t *) \
pthread_getspecific(a_name##_tsd); \
\
if (wrapper == NULL) { \
tsd_init_block_t block; \
wrapper = tsd_init_check_recursion( \
&a_name##_tsd_init_head, &block); \
if (wrapper) \
return (wrapper); \
wrapper = (a_name##_tsd_wrapper_t *) \
malloc_tsd_malloc(sizeof(a_name##_tsd_wrapper_t)); \
block.data = wrapper; \
if (wrapper == NULL) { \
malloc_write("<jemalloc>: Error allocating" \
" TSD for "#a_name"\n"); \
abort(); \
} else { \
static a_type tsd_static_data = a_initializer; \
wrapper->initialized = false; \
wrapper->val = tsd_static_data; \
} \
if (pthread_setspecific(a_name##_tsd, \
(void *)wrapper)) { \
malloc_write("<jemalloc>: Error setting" \
" TSD for "#a_name"\n"); \
abort(); \
} \
tsd_init_finish(&a_name##_tsd_init_head, &block); \
} \
return (wrapper); \
} \
a_attr a_type * \
a_name##_tsd_get(void) \
{ \
a_name##_tsd_wrapper_t *wrapper; \
\
assert(a_name##_booted); \
wrapper = a_name##_tsd_get_wrapper(); \
return (&wrapper->val); \
} \
a_attr void \
a_name##_tsd_set(a_type *val) \
{ \
a_name##_tsd_wrapper_t *wrapper; \
\
assert(a_name##_booted); \
wrapper = a_name##_tsd_get_wrapper(); \
wrapper->val = *(val); \
if (a_cleanup != malloc_tsd_no_cleanup) \
wrapper->initialized = true; \
MALLOC_TSD
#undef O
/* tsd_foo_get(tsd) returns the value of the thread-local instance of foo. */
#define O(n, t, nt) \
JEMALLOC_ALWAYS_INLINE t \
tsd_##n##_get(tsd_t *tsd) { \
return *tsd_##n##p_get(tsd); \
}
#endif
MALLOC_TSD
#undef O
#endif
/* JEMALLOC_H_TYPES */
/******************************************************************************/
#ifdef JEMALLOC_H_STRUCTS
/* tsd_foo_set(tsd, val) updates the thread-local instance of foo to be val. */
#define O(n, t, nt) \
JEMALLOC_ALWAYS_INLINE void \
tsd_##n##_set(tsd_t *tsd, t val) { \
assert(tsd->state != tsd_state_reincarnated && \
tsd->state != tsd_state_minimal_initialized); \
*tsd_##n##p_get(tsd) = val; \
}
MALLOC_TSD
#undef O
#if (!defined(JEMALLOC_MALLOC_THREAD_CLEANUP) && !defined(JEMALLOC_TLS) && \
!defined(_WIN32))
struct
tsd_init_block_s
{
ql_elm
(
tsd_init_block_t
)
link
;
pthread_t
thread
;
void
*
data
;
};
struct
tsd_init_head_s
{
ql_head
(
tsd_init_block_t
)
blocks
;
malloc_mutex_t
lock
;
};
#endif
JEMALLOC_ALWAYS_INLINE
void
tsd_assert_fast
(
tsd_t
*
tsd
)
{
assert
(
!
malloc_slow
&&
tsd_tcache_enabled_get
(
tsd
)
&&
tsd_reentrancy_level_get
(
tsd
)
==
0
);
}
#endif
/* JEMALLOC_H_STRUCTS */
/******************************************************************************/
#ifdef JEMALLOC_H_EXTERNS
JEMALLOC_ALWAYS_INLINE
bool
tsd_fast
(
tsd_t
*
tsd
)
{
bool
fast
=
(
tsd
->
state
==
tsd_state_nominal
);
if
(
fast
)
{
tsd_assert_fast
(
tsd
);
}
void
*
malloc_tsd_malloc
(
size_t
size
);
void
malloc_tsd_dalloc
(
void
*
wrapper
);
void
malloc_tsd_no_cleanup
(
void
*
);
void
malloc_tsd_cleanup_register
(
bool
(
*
f
)(
void
));
void
malloc_tsd_boot
(
void
);
#if (!defined(JEMALLOC_MALLOC_THREAD_CLEANUP) && !defined(JEMALLOC_TLS) && \
!defined(_WIN32))
void
*
tsd_init_check_recursion
(
tsd_init_head_t
*
head
,
tsd_init_block_t
*
block
);
void
tsd_init_finish
(
tsd_init_head_t
*
head
,
tsd_init_block_t
*
block
);
#endif
return
fast
;
}
JEMALLOC_ALWAYS_INLINE
tsd_t
*
tsd_fetch_impl
(
bool
init
,
bool
minimal
)
{
tsd_t
*
tsd
=
tsd_get
(
init
);
if
(
!
init
&&
tsd_get_allocates
()
&&
tsd
==
NULL
)
{
return
NULL
;
}
assert
(
tsd
!=
NULL
);
if
(
unlikely
(
tsd
->
state
!=
tsd_state_nominal
))
{
return
tsd_fetch_slow
(
tsd
,
minimal
);
}
assert
(
tsd_fast
(
tsd
));
tsd_assert_fast
(
tsd
);
return
tsd
;
}
/* Get a minimal TSD that requires no cleanup. See comments in free(). */
JEMALLOC_ALWAYS_INLINE
tsd_t
*
tsd_fetch_min
(
void
)
{
return
tsd_fetch_impl
(
true
,
true
);
}
/* For internal background threads use only. */
JEMALLOC_ALWAYS_INLINE
tsd_t
*
tsd_internal_fetch
(
void
)
{
tsd_t
*
tsd
=
tsd_fetch_min
();
/* Use reincarnated state to prevent full initialization. */
tsd
->
state
=
tsd_state_reincarnated
;
return
tsd
;
}
JEMALLOC_ALWAYS_INLINE
tsd_t
*
tsd_fetch
(
void
)
{
return
tsd_fetch_impl
(
true
,
false
);
}
static
inline
bool
tsd_nominal
(
tsd_t
*
tsd
)
{
return
(
tsd
->
state
<=
tsd_state_nominal_max
);
}
JEMALLOC_ALWAYS_INLINE
tsdn_t
*
tsdn_fetch
(
void
)
{
if
(
!
tsd_booted_get
())
{
return
NULL
;
}
#endif
/* JEMALLOC_H_EXTERNS */
/******************************************************************************/
#ifdef JEMALLOC_H_INLINES
return
tsd_tsdn
(
tsd_fetch_impl
(
false
,
false
));
}
JEMALLOC_ALWAYS_INLINE
rtree_ctx_t
*
tsd_rtree_ctx
(
tsd_t
*
tsd
)
{
return
tsd_rtree_ctxp_get
(
tsd
);
}
JEMALLOC_ALWAYS_INLINE
rtree_ctx_t
*
tsdn_rtree_ctx
(
tsdn_t
*
tsdn
,
rtree_ctx_t
*
fallback
)
{
/*
* If tsd cannot be accessed, initialize the fallback rtree_ctx and
* return a pointer to it.
*/
if
(
unlikely
(
tsdn_null
(
tsdn
)))
{
rtree_ctx_data_init
(
fallback
);
return
fallback
;
}
return
tsd_rtree_ctx
(
tsdn_tsd
(
tsdn
));
}
#endif
/* JEMALLOC_H_INLINES */
/******************************************************************************/
#endif
/* JEMALLOC_INTERNAL_TSD_H */
deps/jemalloc/include/jemalloc/internal/tsd_generic.h
0 → 100644
View file @
f63e81c2
#ifdef JEMALLOC_INTERNAL_TSD_GENERIC_H
#error This file should be included only once, by tsd.h.
#endif
#define JEMALLOC_INTERNAL_TSD_GENERIC_H
typedef
struct
tsd_init_block_s
tsd_init_block_t
;
struct
tsd_init_block_s
{
ql_elm
(
tsd_init_block_t
)
link
;
pthread_t
thread
;
void
*
data
;
};
/* Defined in tsd.c, to allow the mutex headers to have tsd dependencies. */
typedef
struct
tsd_init_head_s
tsd_init_head_t
;
typedef
struct
{
bool
initialized
;
tsd_t
val
;
}
tsd_wrapper_t
;
void
*
tsd_init_check_recursion
(
tsd_init_head_t
*
head
,
tsd_init_block_t
*
block
);
void
tsd_init_finish
(
tsd_init_head_t
*
head
,
tsd_init_block_t
*
block
);
extern
pthread_key_t
tsd_tsd
;
extern
tsd_init_head_t
tsd_init_head
;
extern
tsd_wrapper_t
tsd_boot_wrapper
;
extern
bool
tsd_booted
;
/* Initialization/cleanup. */
JEMALLOC_ALWAYS_INLINE
void
tsd_cleanup_wrapper
(
void
*
arg
)
{
tsd_wrapper_t
*
wrapper
=
(
tsd_wrapper_t
*
)
arg
;
if
(
wrapper
->
initialized
)
{
wrapper
->
initialized
=
false
;
tsd_cleanup
(
&
wrapper
->
val
);
if
(
wrapper
->
initialized
)
{
/* Trigger another cleanup round. */
if
(
pthread_setspecific
(
tsd_tsd
,
(
void
*
)
wrapper
)
!=
0
)
{
malloc_write
(
"<jemalloc>: Error setting TSD
\n
"
);
if
(
opt_abort
)
{
abort
();
}
}
return
;
}
}
malloc_tsd_dalloc
(
wrapper
);
}
JEMALLOC_ALWAYS_INLINE
void
tsd_wrapper_set
(
tsd_wrapper_t
*
wrapper
)
{
if
(
pthread_setspecific
(
tsd_tsd
,
(
void
*
)
wrapper
)
!=
0
)
{
malloc_write
(
"<jemalloc>: Error setting TSD
\n
"
);
abort
();
}
}
JEMALLOC_ALWAYS_INLINE
tsd_wrapper_t
*
tsd_wrapper_get
(
bool
init
)
{
tsd_wrapper_t
*
wrapper
=
(
tsd_wrapper_t
*
)
pthread_getspecific
(
tsd_tsd
);
if
(
init
&&
unlikely
(
wrapper
==
NULL
))
{
tsd_init_block_t
block
;
wrapper
=
(
tsd_wrapper_t
*
)
tsd_init_check_recursion
(
&
tsd_init_head
,
&
block
);
if
(
wrapper
)
{
return
wrapper
;
}
wrapper
=
(
tsd_wrapper_t
*
)
malloc_tsd_malloc
(
sizeof
(
tsd_wrapper_t
));
block
.
data
=
(
void
*
)
wrapper
;
if
(
wrapper
==
NULL
)
{
malloc_write
(
"<jemalloc>: Error allocating TSD
\n
"
);
abort
();
}
else
{
wrapper
->
initialized
=
false
;
tsd_t
initializer
=
TSD_INITIALIZER
;
wrapper
->
val
=
initializer
;
}
tsd_wrapper_set
(
wrapper
);
tsd_init_finish
(
&
tsd_init_head
,
&
block
);
}
return
wrapper
;
}
JEMALLOC_ALWAYS_INLINE
bool
tsd_boot0
(
void
)
{
if
(
pthread_key_create
(
&
tsd_tsd
,
tsd_cleanup_wrapper
)
!=
0
)
{
return
true
;
}
tsd_wrapper_set
(
&
tsd_boot_wrapper
);
tsd_booted
=
true
;
return
false
;
}
JEMALLOC_ALWAYS_INLINE
void
tsd_boot1
(
void
)
{
tsd_wrapper_t
*
wrapper
;
wrapper
=
(
tsd_wrapper_t
*
)
malloc_tsd_malloc
(
sizeof
(
tsd_wrapper_t
));
if
(
wrapper
==
NULL
)
{
malloc_write
(
"<jemalloc>: Error allocating TSD
\n
"
);
abort
();
}
tsd_boot_wrapper
.
initialized
=
false
;
tsd_cleanup
(
&
tsd_boot_wrapper
.
val
);
wrapper
->
initialized
=
false
;
tsd_t
initializer
=
TSD_INITIALIZER
;
wrapper
->
val
=
initializer
;
tsd_wrapper_set
(
wrapper
);
}
JEMALLOC_ALWAYS_INLINE
bool
tsd_boot
(
void
)
{
if
(
tsd_boot0
())
{
return
true
;
}
tsd_boot1
();
return
false
;
}
JEMALLOC_ALWAYS_INLINE
bool
tsd_booted_get
(
void
)
{
return
tsd_booted
;
}
JEMALLOC_ALWAYS_INLINE
bool
tsd_get_allocates
(
void
)
{
return
true
;
}
/* Get/set. */
JEMALLOC_ALWAYS_INLINE
tsd_t
*
tsd_get
(
bool
init
)
{
tsd_wrapper_t
*
wrapper
;
assert
(
tsd_booted
);
wrapper
=
tsd_wrapper_get
(
init
);
if
(
tsd_get_allocates
()
&&
!
init
&&
wrapper
==
NULL
)
{
return
NULL
;
}
return
&
wrapper
->
val
;
}
JEMALLOC_ALWAYS_INLINE
void
tsd_set
(
tsd_t
*
val
)
{
tsd_wrapper_t
*
wrapper
;
assert
(
tsd_booted
);
wrapper
=
tsd_wrapper_get
(
true
);
if
(
likely
(
&
wrapper
->
val
!=
val
))
{
wrapper
->
val
=
*
(
val
);
}
wrapper
->
initialized
=
true
;
}
deps/jemalloc/include/jemalloc/internal/tsd_malloc_thread_cleanup.h
0 → 100644
View file @
f63e81c2
#ifdef JEMALLOC_INTERNAL_TSD_MALLOC_THREAD_CLEANUP_H
#error This file should be included only once, by tsd.h.
#endif
#define JEMALLOC_INTERNAL_TSD_MALLOC_THREAD_CLEANUP_H
extern
__thread
tsd_t
tsd_tls
;
extern
__thread
bool
tsd_initialized
;
extern
bool
tsd_booted
;
/* Initialization/cleanup. */
JEMALLOC_ALWAYS_INLINE
bool
tsd_cleanup_wrapper
(
void
)
{
if
(
tsd_initialized
)
{
tsd_initialized
=
false
;
tsd_cleanup
(
&
tsd_tls
);
}
return
tsd_initialized
;
}
JEMALLOC_ALWAYS_INLINE
bool
tsd_boot0
(
void
)
{
malloc_tsd_cleanup_register
(
&
tsd_cleanup_wrapper
);
tsd_booted
=
true
;
return
false
;
}
JEMALLOC_ALWAYS_INLINE
void
tsd_boot1
(
void
)
{
/* Do nothing. */
}
JEMALLOC_ALWAYS_INLINE
bool
tsd_boot
(
void
)
{
return
tsd_boot0
();
}
JEMALLOC_ALWAYS_INLINE
bool
tsd_booted_get
(
void
)
{
return
tsd_booted
;
}
JEMALLOC_ALWAYS_INLINE
bool
tsd_get_allocates
(
void
)
{
return
false
;
}
/* Get/set. */
JEMALLOC_ALWAYS_INLINE
tsd_t
*
tsd_get
(
bool
init
)
{
assert
(
tsd_booted
);
return
&
tsd_tls
;
}
JEMALLOC_ALWAYS_INLINE
void
tsd_set
(
tsd_t
*
val
)
{
assert
(
tsd_booted
);
if
(
likely
(
&
tsd_tls
!=
val
))
{
tsd_tls
=
(
*
val
);
}
tsd_initialized
=
true
;
}
deps/jemalloc/include/jemalloc/internal/tsd_tls.h
0 → 100644
View file @
f63e81c2
#ifdef JEMALLOC_INTERNAL_TSD_TLS_H
#error This file should be included only once, by tsd.h.
#endif
#define JEMALLOC_INTERNAL_TSD_TLS_H
extern
__thread
tsd_t
tsd_tls
;
extern
pthread_key_t
tsd_tsd
;
extern
bool
tsd_booted
;
/* Initialization/cleanup. */
JEMALLOC_ALWAYS_INLINE
bool
tsd_boot0
(
void
)
{
if
(
pthread_key_create
(
&
tsd_tsd
,
&
tsd_cleanup
)
!=
0
)
{
return
true
;
}
tsd_booted
=
true
;
return
false
;
}
JEMALLOC_ALWAYS_INLINE
void
tsd_boot1
(
void
)
{
/* Do nothing. */
}
JEMALLOC_ALWAYS_INLINE
bool
tsd_boot
(
void
)
{
return
tsd_boot0
();
}
JEMALLOC_ALWAYS_INLINE
bool
tsd_booted_get
(
void
)
{
return
tsd_booted
;
}
JEMALLOC_ALWAYS_INLINE
bool
tsd_get_allocates
(
void
)
{
return
false
;
}
/* Get/set. */
JEMALLOC_ALWAYS_INLINE
tsd_t
*
tsd_get
(
UNUSED
bool
init
)
{
assert
(
tsd_booted
);
return
&
tsd_tls
;
}
JEMALLOC_ALWAYS_INLINE
void
tsd_set
(
tsd_t
*
val
)
{
assert
(
tsd_booted
);
if
(
likely
(
&
tsd_tls
!=
val
))
{
tsd_tls
=
(
*
val
);
}
if
(
pthread_setspecific
(
tsd_tsd
,
(
void
*
)(
&
tsd_tls
))
!=
0
)
{
malloc_write
(
"<jemalloc>: Error setting tsd.
\n
"
);
if
(
opt_abort
)
{
abort
();
}
}
}
deps/jemalloc/include/jemalloc/internal/tsd_types.h
0 → 100644
View file @
f63e81c2
#ifndef JEMALLOC_INTERNAL_TSD_TYPES_H
#define JEMALLOC_INTERNAL_TSD_TYPES_H
#define MALLOC_TSD_CLEANUPS_MAX 2
typedef
struct
tsd_s
tsd_t
;
typedef
struct
tsdn_s
tsdn_t
;
typedef
bool
(
*
malloc_tsd_cleanup_t
)(
void
);
#endif
/* JEMALLOC_INTERNAL_TSD_TYPES_H */
deps/jemalloc/include/jemalloc/internal/tsd_win.h
0 → 100644
View file @
f63e81c2
#ifdef JEMALLOC_INTERNAL_TSD_WIN_H
#error This file should be included only once, by tsd.h.
#endif
#define JEMALLOC_INTERNAL_TSD_WIN_H
typedef
struct
{
bool
initialized
;
tsd_t
val
;
}
tsd_wrapper_t
;
extern
DWORD
tsd_tsd
;
extern
tsd_wrapper_t
tsd_boot_wrapper
;
extern
bool
tsd_booted
;
/* Initialization/cleanup. */
JEMALLOC_ALWAYS_INLINE
bool
tsd_cleanup_wrapper
(
void
)
{
DWORD
error
=
GetLastError
();
tsd_wrapper_t
*
wrapper
=
(
tsd_wrapper_t
*
)
TlsGetValue
(
tsd_tsd
);
SetLastError
(
error
);
if
(
wrapper
==
NULL
)
{
return
false
;
}
if
(
wrapper
->
initialized
)
{
wrapper
->
initialized
=
false
;
tsd_cleanup
(
&
wrapper
->
val
);
if
(
wrapper
->
initialized
)
{
/* Trigger another cleanup round. */
return
true
;
}
}
malloc_tsd_dalloc
(
wrapper
);
return
false
;
}
JEMALLOC_ALWAYS_INLINE
void
tsd_wrapper_set
(
tsd_wrapper_t
*
wrapper
)
{
if
(
!
TlsSetValue
(
tsd_tsd
,
(
void
*
)
wrapper
))
{
malloc_write
(
"<jemalloc>: Error setting TSD
\n
"
);
abort
();
}
}
JEMALLOC_ALWAYS_INLINE
tsd_wrapper_t
*
tsd_wrapper_get
(
bool
init
)
{
DWORD
error
=
GetLastError
();
tsd_wrapper_t
*
wrapper
=
(
tsd_wrapper_t
*
)
TlsGetValue
(
tsd_tsd
);
SetLastError
(
error
);
if
(
init
&&
unlikely
(
wrapper
==
NULL
))
{
wrapper
=
(
tsd_wrapper_t
*
)
malloc_tsd_malloc
(
sizeof
(
tsd_wrapper_t
));
if
(
wrapper
==
NULL
)
{
malloc_write
(
"<jemalloc>: Error allocating TSD
\n
"
);
abort
();
}
else
{
wrapper
->
initialized
=
false
;
/* MSVC is finicky about aggregate initialization. */
tsd_t
tsd_initializer
=
TSD_INITIALIZER
;
wrapper
->
val
=
tsd_initializer
;
}
tsd_wrapper_set
(
wrapper
);
}
return
wrapper
;
}
JEMALLOC_ALWAYS_INLINE
bool
tsd_boot0
(
void
)
{
tsd_tsd
=
TlsAlloc
();
if
(
tsd_tsd
==
TLS_OUT_OF_INDEXES
)
{
return
true
;
}
malloc_tsd_cleanup_register
(
&
tsd_cleanup_wrapper
);
tsd_wrapper_set
(
&
tsd_boot_wrapper
);
tsd_booted
=
true
;
return
false
;
}
JEMALLOC_ALWAYS_INLINE
void
tsd_boot1
(
void
)
{
tsd_wrapper_t
*
wrapper
;
wrapper
=
(
tsd_wrapper_t
*
)
malloc_tsd_malloc
(
sizeof
(
tsd_wrapper_t
));
if
(
wrapper
==
NULL
)
{
malloc_write
(
"<jemalloc>: Error allocating TSD
\n
"
);
abort
();
}
tsd_boot_wrapper
.
initialized
=
false
;
tsd_cleanup
(
&
tsd_boot_wrapper
.
val
);
wrapper
->
initialized
=
false
;
tsd_t
initializer
=
TSD_INITIALIZER
;
wrapper
->
val
=
initializer
;
tsd_wrapper_set
(
wrapper
);
}
JEMALLOC_ALWAYS_INLINE
bool
tsd_boot
(
void
)
{
if
(
tsd_boot0
())
{
return
true
;
}
tsd_boot1
();
return
false
;
}
JEMALLOC_ALWAYS_INLINE
bool
tsd_booted_get
(
void
)
{
return
tsd_booted
;
}
JEMALLOC_ALWAYS_INLINE
bool
tsd_get_allocates
(
void
)
{
return
true
;
}
/* Get/set. */
JEMALLOC_ALWAYS_INLINE
tsd_t
*
tsd_get
(
bool
init
)
{
tsd_wrapper_t
*
wrapper
;
assert
(
tsd_booted
);
wrapper
=
tsd_wrapper_get
(
init
);
if
(
tsd_get_allocates
()
&&
!
init
&&
wrapper
==
NULL
)
{
return
NULL
;
}
return
&
wrapper
->
val
;
}
JEMALLOC_ALWAYS_INLINE
void
tsd_set
(
tsd_t
*
val
)
{
tsd_wrapper_t
*
wrapper
;
assert
(
tsd_booted
);
wrapper
=
tsd_wrapper_get
(
true
);
if
(
likely
(
&
wrapper
->
val
!=
val
))
{
wrapper
->
val
=
*
(
val
);
}
wrapper
->
initialized
=
true
;
}
deps/jemalloc/include/jemalloc/internal/util.h
View file @
f63e81c2
/******************************************************************************/
#
if
def JEMALLOC_
H_TYPES
#ifndef JEMALLOC_INTERNAL_UTIL_H
#def
ine
JEMALLOC_
INTERNAL_UTIL_H
/* Size of stack-allocated buffer passed to buferror(). */
#define BUFERROR_BUF 64
#define UTIL_INLINE static inline
/*
* Size of stack-allocated buffer used by malloc_{,v,vc}printf(). This must be
* large enough for all possible uses within jemalloc.
*/
#define MALLOC_PRINTF_BUFSIZE 4096
/* Junk fill patterns. */
#ifndef JEMALLOC_ALLOC_JUNK
# define JEMALLOC_ALLOC_JUNK ((uint8_t)0xa5)
#endif
#ifndef JEMALLOC_FREE_JUNK
# define JEMALLOC_FREE_JUNK ((uint8_t)0x5a)
#endif
/*
* Wrap a cpp argument that contains commas such that it isn't broken up into
...
...
@@ -16,128 +17,34 @@
*/
#define JEMALLOC_ARG_CONCAT(...) __VA_ARGS__
/* cpp macro definition stringification. */
#define STRINGIFY_HELPER(x) #x
#define STRINGIFY(x) STRINGIFY_HELPER(x)
/*
* Silence compiler warnings due to uninitialized values. This is used
* wherever the compiler fails to recognize that the variable is never used
* uninitialized.
*/
#ifdef JEMALLOC_CC_SILENCE
# define JEMALLOC_CC_SILENCE_INIT(v) = v
#else
# define JEMALLOC_CC_SILENCE_INIT(v)
#endif
/*
* Define a custom assert() in order to reduce the chances of deadlock during
* assertion failure.
*/
#ifndef assert
#define assert(e) do { \
if (config_debug && !(e)) { \
malloc_printf( \
"<jemalloc>: %s:%d: Failed assertion: \"%s\"\n", \
__FILE__, __LINE__, #e); \
abort(); \
} \
} while (0)
#endif
#ifndef not_reached
#define not_reached() do { \
if (config_debug) { \
malloc_printf( \
"<jemalloc>: %s:%d: Unreachable code reached\n", \
__FILE__, __LINE__); \
abort(); \
} \
} while (0)
#endif
#ifndef not_implemented
#define not_implemented() do { \
if (config_debug) { \
malloc_printf("<jemalloc>: %s:%d: Not implemented\n", \
__FILE__, __LINE__); \
abort(); \
} \
} while (0)
#endif
#define JEMALLOC_CC_SILENCE_INIT(v) = v
#ifndef assert_not_implemented
#define assert_not_implemented(e) do { \
if (config_debug && !(e)) \
not_implemented(); \
} while (0)
#endif
/* Use to assert a particular configuration, e.g., cassert(config_debug). */
#define cassert(c) do { \
if ((c) == false) \
not_reached(); \
} while (0)
#endif
/* JEMALLOC_H_TYPES */
/******************************************************************************/
#ifdef JEMALLOC_H_STRUCTS
#endif
/* JEMALLOC_H_STRUCTS */
/******************************************************************************/
#ifdef JEMALLOC_H_EXTERNS
int
buferror
(
int
err
,
char
*
buf
,
size_t
buflen
);
uintmax_t
malloc_strtoumax
(
const
char
*
restrict
nptr
,
char
**
restrict
endptr
,
int
base
);
void
malloc_write
(
const
char
*
s
);
/*
* malloc_vsnprintf() supports a subset of snprintf(3) that avoids floating
* point math.
*/
int
malloc_vsnprintf
(
char
*
str
,
size_t
size
,
const
char
*
format
,
va_list
ap
);
int
malloc_snprintf
(
char
*
str
,
size_t
size
,
const
char
*
format
,
...)
JEMALLOC_ATTR
(
format
(
printf
,
3
,
4
));
void
malloc_vcprintf
(
void
(
*
write_cb
)(
void
*
,
const
char
*
),
void
*
cbopaque
,
const
char
*
format
,
va_list
ap
);
void
malloc_cprintf
(
void
(
*
write
)(
void
*
,
const
char
*
),
void
*
cbopaque
,
const
char
*
format
,
...)
JEMALLOC_ATTR
(
format
(
printf
,
3
,
4
));
void
malloc_printf
(
const
char
*
format
,
...)
JEMALLOC_ATTR
(
format
(
printf
,
1
,
2
));
#endif
/* JEMALLOC_H_EXTERNS */
/******************************************************************************/
#ifdef JEMALLOC_H_INLINES
#ifndef JEMALLOC_ENABLE_INLINE
size_t
pow2_ceil
(
size_t
x
);
void
set_errno
(
int
errnum
);
int
get_errno
(
void
);
#ifdef __GNUC__
# define likely(x) __builtin_expect(!!(x), 1)
# define unlikely(x) __builtin_expect(!!(x), 0)
#else
# define likely(x) !!(x)
# define unlikely(x) !!(x)
#endif
#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_UTIL_C_))
/* Compute the smallest power of 2 that is >= x. */
JEMALLOC_INLINE
size_t
pow2_ceil
(
size_t
x
)
{
x
--
;
x
|=
x
>>
1
;
x
|=
x
>>
2
;
x
|=
x
>>
4
;
x
|=
x
>>
8
;
x
|=
x
>>
16
;
#if (LG_SIZEOF_PTR == 3)
x
|=
x
>>
32
;
#if !defined(JEMALLOC_INTERNAL_UNREACHABLE)
# error JEMALLOC_INTERNAL_UNREACHABLE should have been defined by configure
#endif
x
++
;
return
(
x
);
}
/* Sets error code */
JEMALLOC_INLINE
void
set_errno
(
int
errnum
)
{
#define unreachable() JEMALLOC_INTERNAL_UNREACHABLE()
/* Set error code. */
UTIL_INLINE
void
set_errno
(
int
errnum
)
{
#ifdef _WIN32
SetLastError
(
errnum
);
#else
...
...
@@ -145,18 +52,16 @@ set_errno(int errnum)
#endif
}
/* Get last error code */
JEMALLOC_INLINE
int
get_errno
(
void
)
{
/* Get last error code. */
UTIL_INLINE
int
get_errno
(
void
)
{
#ifdef _WIN32
return
(
GetLastError
()
)
;
return
GetLastError
();
#else
return
(
errno
)
;
return
errno
;
#endif
}
#endif
#endif
/* JEMALLOC_H_INLINES */
/******************************************************************************/
#undef UTIL_INLINE
#endif
/* JEMALLOC_INTERNAL_UTIL_H */
deps/jemalloc/include/jemalloc/internal/witness.h
0 → 100644
View file @
f63e81c2
#ifndef JEMALLOC_INTERNAL_WITNESS_H
#define JEMALLOC_INTERNAL_WITNESS_H
#include "jemalloc/internal/ql.h"
/******************************************************************************/
/* LOCK RANKS */
/******************************************************************************/
/*
* Witnesses with rank WITNESS_RANK_OMIT are completely ignored by the witness
* machinery.
*/
#define WITNESS_RANK_OMIT 0U
#define WITNESS_RANK_MIN 1U
#define WITNESS_RANK_INIT 1U
#define WITNESS_RANK_CTL 1U
#define WITNESS_RANK_TCACHES 2U
#define WITNESS_RANK_ARENAS 3U
#define WITNESS_RANK_BACKGROUND_THREAD_GLOBAL 4U
#define WITNESS_RANK_PROF_DUMP 5U
#define WITNESS_RANK_PROF_BT2GCTX 6U
#define WITNESS_RANK_PROF_TDATAS 7U
#define WITNESS_RANK_PROF_TDATA 8U
#define WITNESS_RANK_PROF_GCTX 9U
#define WITNESS_RANK_BACKGROUND_THREAD 10U
/*
* Used as an argument to witness_assert_depth_to_rank() in order to validate
* depth excluding non-core locks with lower ranks. Since the rank argument to
* witness_assert_depth_to_rank() is inclusive rather than exclusive, this
* definition can have the same value as the minimally ranked core lock.
*/
#define WITNESS_RANK_CORE 11U
#define WITNESS_RANK_DECAY 11U
#define WITNESS_RANK_TCACHE_QL 12U
#define WITNESS_RANK_EXTENT_GROW 13U
#define WITNESS_RANK_EXTENTS 14U
#define WITNESS_RANK_EXTENT_AVAIL 15U
#define WITNESS_RANK_EXTENT_POOL 16U
#define WITNESS_RANK_RTREE 17U
#define WITNESS_RANK_BASE 18U
#define WITNESS_RANK_ARENA_LARGE 19U
#define WITNESS_RANK_LEAF 0xffffffffU
#define WITNESS_RANK_BIN WITNESS_RANK_LEAF
#define WITNESS_RANK_ARENA_STATS WITNESS_RANK_LEAF
#define WITNESS_RANK_DSS WITNESS_RANK_LEAF
#define WITNESS_RANK_PROF_ACTIVE WITNESS_RANK_LEAF
#define WITNESS_RANK_PROF_ACCUM WITNESS_RANK_LEAF
#define WITNESS_RANK_PROF_DUMP_SEQ WITNESS_RANK_LEAF
#define WITNESS_RANK_PROF_GDUMP WITNESS_RANK_LEAF
#define WITNESS_RANK_PROF_NEXT_THR_UID WITNESS_RANK_LEAF
#define WITNESS_RANK_PROF_THREAD_ACTIVE_INIT WITNESS_RANK_LEAF
/******************************************************************************/
/* PER-WITNESS DATA */
/******************************************************************************/
#if defined(JEMALLOC_DEBUG)
# define WITNESS_INITIALIZER(name, rank) {name, rank, NULL, NULL, {NULL, NULL}}
#else
# define WITNESS_INITIALIZER(name, rank)
#endif
typedef
struct
witness_s
witness_t
;
typedef
unsigned
witness_rank_t
;
typedef
ql_head
(
witness_t
)
witness_list_t
;
typedef
int
witness_comp_t
(
const
witness_t
*
,
void
*
,
const
witness_t
*
,
void
*
);
struct
witness_s
{
/* Name, used for printing lock order reversal messages. */
const
char
*
name
;
/*
* Witness rank, where 0 is lowest and UINT_MAX is highest. Witnesses
* must be acquired in order of increasing rank.
*/
witness_rank_t
rank
;
/*
* If two witnesses are of equal rank and they have the samp comp
* function pointer, it is called as a last attempt to differentiate
* between witnesses of equal rank.
*/
witness_comp_t
*
comp
;
/* Opaque data, passed to comp(). */
void
*
opaque
;
/* Linkage for thread's currently owned locks. */
ql_elm
(
witness_t
)
link
;
};
/******************************************************************************/
/* PER-THREAD DATA */
/******************************************************************************/
typedef
struct
witness_tsd_s
witness_tsd_t
;
struct
witness_tsd_s
{
witness_list_t
witnesses
;
bool
forking
;
};
#define WITNESS_TSD_INITIALIZER { ql_head_initializer(witnesses), false }
#define WITNESS_TSDN_NULL ((witness_tsdn_t *)0)
/******************************************************************************/
/* (PER-THREAD) NULLABILITY HELPERS */
/******************************************************************************/
typedef
struct
witness_tsdn_s
witness_tsdn_t
;
struct
witness_tsdn_s
{
witness_tsd_t
witness_tsd
;
};
JEMALLOC_ALWAYS_INLINE
witness_tsdn_t
*
witness_tsd_tsdn
(
witness_tsd_t
*
witness_tsd
)
{
return
(
witness_tsdn_t
*
)
witness_tsd
;
}
JEMALLOC_ALWAYS_INLINE
bool
witness_tsdn_null
(
witness_tsdn_t
*
witness_tsdn
)
{
return
witness_tsdn
==
NULL
;
}
JEMALLOC_ALWAYS_INLINE
witness_tsd_t
*
witness_tsdn_tsd
(
witness_tsdn_t
*
witness_tsdn
)
{
assert
(
!
witness_tsdn_null
(
witness_tsdn
));
return
&
witness_tsdn
->
witness_tsd
;
}
/******************************************************************************/
/* API */
/******************************************************************************/
void
witness_init
(
witness_t
*
witness
,
const
char
*
name
,
witness_rank_t
rank
,
witness_comp_t
*
comp
,
void
*
opaque
);
typedef
void
(
witness_lock_error_t
)(
const
witness_list_t
*
,
const
witness_t
*
);
extern
witness_lock_error_t
*
JET_MUTABLE
witness_lock_error
;
typedef
void
(
witness_owner_error_t
)(
const
witness_t
*
);
extern
witness_owner_error_t
*
JET_MUTABLE
witness_owner_error
;
typedef
void
(
witness_not_owner_error_t
)(
const
witness_t
*
);
extern
witness_not_owner_error_t
*
JET_MUTABLE
witness_not_owner_error
;
typedef
void
(
witness_depth_error_t
)(
const
witness_list_t
*
,
witness_rank_t
rank_inclusive
,
unsigned
depth
);
extern
witness_depth_error_t
*
JET_MUTABLE
witness_depth_error
;
void
witnesses_cleanup
(
witness_tsd_t
*
witness_tsd
);
void
witness_prefork
(
witness_tsd_t
*
witness_tsd
);
void
witness_postfork_parent
(
witness_tsd_t
*
witness_tsd
);
void
witness_postfork_child
(
witness_tsd_t
*
witness_tsd
);
/* Helper, not intended for direct use. */
static
inline
bool
witness_owner
(
witness_tsd_t
*
witness_tsd
,
const
witness_t
*
witness
)
{
witness_list_t
*
witnesses
;
witness_t
*
w
;
cassert
(
config_debug
);
witnesses
=
&
witness_tsd
->
witnesses
;
ql_foreach
(
w
,
witnesses
,
link
)
{
if
(
w
==
witness
)
{
return
true
;
}
}
return
false
;
}
static
inline
void
witness_assert_owner
(
witness_tsdn_t
*
witness_tsdn
,
const
witness_t
*
witness
)
{
witness_tsd_t
*
witness_tsd
;
if
(
!
config_debug
)
{
return
;
}
if
(
witness_tsdn_null
(
witness_tsdn
))
{
return
;
}
witness_tsd
=
witness_tsdn_tsd
(
witness_tsdn
);
if
(
witness
->
rank
==
WITNESS_RANK_OMIT
)
{
return
;
}
if
(
witness_owner
(
witness_tsd
,
witness
))
{
return
;
}
witness_owner_error
(
witness
);
}
static
inline
void
witness_assert_not_owner
(
witness_tsdn_t
*
witness_tsdn
,
const
witness_t
*
witness
)
{
witness_tsd_t
*
witness_tsd
;
witness_list_t
*
witnesses
;
witness_t
*
w
;
if
(
!
config_debug
)
{
return
;
}
if
(
witness_tsdn_null
(
witness_tsdn
))
{
return
;
}
witness_tsd
=
witness_tsdn_tsd
(
witness_tsdn
);
if
(
witness
->
rank
==
WITNESS_RANK_OMIT
)
{
return
;
}
witnesses
=
&
witness_tsd
->
witnesses
;
ql_foreach
(
w
,
witnesses
,
link
)
{
if
(
w
==
witness
)
{
witness_not_owner_error
(
witness
);
}
}
}
static
inline
void
witness_assert_depth_to_rank
(
witness_tsdn_t
*
witness_tsdn
,
witness_rank_t
rank_inclusive
,
unsigned
depth
)
{
witness_tsd_t
*
witness_tsd
;
unsigned
d
;
witness_list_t
*
witnesses
;
witness_t
*
w
;
if
(
!
config_debug
)
{
return
;
}
if
(
witness_tsdn_null
(
witness_tsdn
))
{
return
;
}
witness_tsd
=
witness_tsdn_tsd
(
witness_tsdn
);
d
=
0
;
witnesses
=
&
witness_tsd
->
witnesses
;
w
=
ql_last
(
witnesses
,
link
);
if
(
w
!=
NULL
)
{
ql_reverse_foreach
(
w
,
witnesses
,
link
)
{
if
(
w
->
rank
<
rank_inclusive
)
{
break
;
}
d
++
;
}
}
if
(
d
!=
depth
)
{
witness_depth_error
(
witnesses
,
rank_inclusive
,
depth
);
}
}
static
inline
void
witness_assert_depth
(
witness_tsdn_t
*
witness_tsdn
,
unsigned
depth
)
{
witness_assert_depth_to_rank
(
witness_tsdn
,
WITNESS_RANK_MIN
,
depth
);
}
static
inline
void
witness_assert_lockless
(
witness_tsdn_t
*
witness_tsdn
)
{
witness_assert_depth
(
witness_tsdn
,
0
);
}
static
inline
void
witness_lock
(
witness_tsdn_t
*
witness_tsdn
,
witness_t
*
witness
)
{
witness_tsd_t
*
witness_tsd
;
witness_list_t
*
witnesses
;
witness_t
*
w
;
if
(
!
config_debug
)
{
return
;
}
if
(
witness_tsdn_null
(
witness_tsdn
))
{
return
;
}
witness_tsd
=
witness_tsdn_tsd
(
witness_tsdn
);
if
(
witness
->
rank
==
WITNESS_RANK_OMIT
)
{
return
;
}
witness_assert_not_owner
(
witness_tsdn
,
witness
);
witnesses
=
&
witness_tsd
->
witnesses
;
w
=
ql_last
(
witnesses
,
link
);
if
(
w
==
NULL
)
{
/* No other locks; do nothing. */
}
else
if
(
witness_tsd
->
forking
&&
w
->
rank
<=
witness
->
rank
)
{
/* Forking, and relaxed ranking satisfied. */
}
else
if
(
w
->
rank
>
witness
->
rank
)
{
/* Not forking, rank order reversal. */
witness_lock_error
(
witnesses
,
witness
);
}
else
if
(
w
->
rank
==
witness
->
rank
&&
(
w
->
comp
==
NULL
||
w
->
comp
!=
witness
->
comp
||
w
->
comp
(
w
,
w
->
opaque
,
witness
,
witness
->
opaque
)
>
0
))
{
/*
* Missing/incompatible comparison function, or comparison
* function indicates rank order reversal.
*/
witness_lock_error
(
witnesses
,
witness
);
}
ql_elm_new
(
witness
,
link
);
ql_tail_insert
(
witnesses
,
witness
,
link
);
}
static
inline
void
witness_unlock
(
witness_tsdn_t
*
witness_tsdn
,
witness_t
*
witness
)
{
witness_tsd_t
*
witness_tsd
;
witness_list_t
*
witnesses
;
if
(
!
config_debug
)
{
return
;
}
if
(
witness_tsdn_null
(
witness_tsdn
))
{
return
;
}
witness_tsd
=
witness_tsdn_tsd
(
witness_tsdn
);
if
(
witness
->
rank
==
WITNESS_RANK_OMIT
)
{
return
;
}
/*
* Check whether owner before removal, rather than relying on
* witness_assert_owner() to abort, so that unit tests can test this
* function's failure mode without causing undefined behavior.
*/
if
(
witness_owner
(
witness_tsd
,
witness
))
{
witnesses
=
&
witness_tsd
->
witnesses
;
ql_remove
(
witnesses
,
witness
,
link
);
}
else
{
witness_assert_owner
(
witness_tsdn
,
witness
);
}
}
#endif
/* JEMALLOC_INTERNAL_WITNESS_H */
deps/jemalloc/include/jemalloc/jemalloc.sh
View file @
f63e81c2
...
...
@@ -12,17 +12,16 @@ extern "C" {
EOF
for
hdr
in
jemalloc_defs.h jemalloc_rename.h jemalloc_macros.h
\
jemalloc_protos.h jemalloc_mangle.h
;
do
jemalloc_protos.h
jemalloc_typedefs.h
jemalloc_mangle.h
;
do
cat
"
${
objroot
}
include/jemalloc/
${
hdr
}
"
\
|
grep
-v
'Generated from .* by configure\.'
\
|
sed
-e
's/^#define /#define /g'
\
|
sed
-e
's/ $//g'
echo
done
cat
<<
EOF
#ifdef __cplusplus
}
;
}
#endif
#endif /* JEMALLOC_H_ */
EOF
deps/jemalloc/include/jemalloc/jemalloc_defs.h.in
View file @
f63e81c2
/* Defined if __attribute__((...)) syntax is supported. */
#undef JEMALLOC_HAVE_ATTR
/* Support the experimental API. */
#undef JEMALLOC_EXPERIMENTAL
/* Defined if alloc_size attribute is supported. */
#undef JEMALLOC_HAVE_ATTR_ALLOC_SIZE
/* Defined if format(gnu_printf, ...) attribute is supported. */
#undef JEMALLOC_HAVE_ATTR_FORMAT_GNU_PRINTF
/* Defined if format(printf, ...) attribute is supported. */
#undef JEMALLOC_HAVE_ATTR_FORMAT_PRINTF
/*
* Define overrides for non-standard allocator-related functions if they are
...
...
@@ -20,5 +26,20 @@
*/
#undef JEMALLOC_USABLE_SIZE_CONST
/*
* If defined, specify throw() for the public function prototypes when compiling
* with C++. The only justification for this is to match the prototypes that
* glibc defines.
*/
#undef JEMALLOC_USE_CXX_THROW
#ifdef _MSC_VER
# ifdef _WIN64
# define LG_SIZEOF_PTR_WIN 3
# else
# define LG_SIZEOF_PTR_WIN 2
# endif
#endif
/* sizeof(void *) == 2^LG_SIZEOF_PTR. */
#undef LG_SIZEOF_PTR
deps/jemalloc/include/jemalloc/jemalloc_macros.h.in
View file @
f63e81c2
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <limits.h>
#include <strings.h>
...
...
@@ -8,54 +11,116 @@
#define JEMALLOC_VERSION_NREV @jemalloc_version_nrev@
#define JEMALLOC_VERSION_GID "@jemalloc_version_gid@"
#
define MALLOCX_LG_ALIGN(la) (la)
#
if LG_SIZEOF_PTR == 2
#
define MALLOCX_ALIGN(a) (
ffs(a
)-1)
#
else
#define MALLOCX_LG_ALIGN(la)
((int)
(la)
)
#if LG_SIZEOF_PTR == 2
# define MALLOCX_ALIGN(a) (
(int)(ffs((int)(a)
)-1)
)
#else
# define MALLOCX_ALIGN(a) \
((a < (size_t)INT_MAX) ? ffs(a)-1 : ffs(a>>32)+31)
# endif
# define MALLOCX_ZERO ((int)0x40)
/* Bias arena index bits so that 0 encodes "MALLOCX_ARENA() unspecified". */
# define MALLOCX_ARENA(a) ((int)(((a)+1) << 8))
((int)(((size_t)(a) < (size_t)INT_MAX) ? ffs((int)(a))-1 : \
ffs((int)(((size_t)(a))>>32))+31))
#endif
#define MALLOCX_ZERO ((int)0x40)
/*
* Bias tcache index bits so that 0 encodes "automatic tcache management", and 1
* encodes MALLOCX_TCACHE_NONE.
*/
#define MALLOCX_TCACHE(tc) ((int)(((tc)+2) << 8))
#define MALLOCX_TCACHE_NONE MALLOCX_TCACHE(-1)
/*
* Bias arena index bits so that 0 encodes "use an automatically chosen arena".
*/
#define MALLOCX_ARENA(a) ((((int)(a))+1) << 20)
#ifdef JEMALLOC_EXPERIMENTAL
# define ALLOCM_LG_ALIGN(la) (la)
# if LG_SIZEOF_PTR == 2
# define ALLOCM_ALIGN(a) (ffs(a)-1)
# else
# define ALLOCM_ALIGN(a) \
((a < (size_t)INT_MAX) ? ffs(a)-1 : ffs(a>>32)+31)
# endif
# define ALLOCM_ZERO ((int)0x40)
# define ALLOCM_NO_MOVE ((int)0x80)
/* Bias arena index bits so that 0 encodes "ALLOCM_ARENA() unspecified". */
# define ALLOCM_ARENA(a) ((int)(((a)+1) << 8))
# define ALLOCM_SUCCESS 0
# define ALLOCM_ERR_OOM 1
# define ALLOCM_ERR_NOT_MOVED 2
/*
* Use as arena index in "arena.<i>.{purge,decay,dss}" and
* "stats.arenas.<i>.*" mallctl interfaces to select all arenas. This
* definition is intentionally specified in raw decimal format to support
* cpp-based string concatenation, e.g.
*
* #define STRINGIFY_HELPER(x) #x
* #define STRINGIFY(x) STRINGIFY_HELPER(x)
*
* mallctl("arena." STRINGIFY(MALLCTL_ARENAS_ALL) ".purge", NULL, NULL, NULL,
* 0);
*/
#define MALLCTL_ARENAS_ALL 4096
/*
* Use as arena index in "stats.arenas.<i>.*" mallctl interfaces to select
* destroyed arenas.
*/
#define MALLCTL_ARENAS_DESTROYED 4097
#if defined(__cplusplus) && defined(JEMALLOC_USE_CXX_THROW)
# define JEMALLOC_CXX_THROW throw()
#else
# define JEMALLOC_CXX_THROW
#endif
#ifdef JEMALLOC_HAVE_ATTR
# define JEMALLOC_ATTR(s) __attribute__((s))
# define JEMALLOC_EXPORT JEMALLOC_ATTR(visibility("default"))
# define JEMALLOC_ALIGNED(s) JEMALLOC_ATTR(aligned(s))
# define JEMALLOC_SECTION(s) JEMALLOC_ATTR(section(s))
# define JEMALLOC_NOINLINE JEMALLOC_ATTR(noinline)
#elif _MSC_VER
#if defined(_MSC_VER)
# define JEMALLOC_ATTR(s)
# define JEMALLOC_ALIGNED(s) __declspec(align(s))
# define JEMALLOC_ALLOC_SIZE(s)
# define JEMALLOC_ALLOC_SIZE2(s1, s2)
# ifndef JEMALLOC_EXPORT
# ifdef DLLEXPORT
# define JEMALLOC_EXPORT __declspec(dllexport)
# else
# define JEMALLOC_EXPORT __declspec(dllimport)
# endif
#
define JEMALLOC_ALIGNED(s) __declspec(align(s))
# define JEMALLOC_
SECTION(s) __declspec(allocate(s)
)
#
endif
# define JEMALLOC_
FORMAT_PRINTF(s, i
)
# define JEMALLOC_NOINLINE __declspec(noinline)
# ifdef __cplusplus
# define JEMALLOC_NOTHROW __declspec(nothrow)
# else
# define JEMALLOC_NOTHROW
# endif
# define JEMALLOC_SECTION(s) __declspec(allocate(s))
# define JEMALLOC_RESTRICT_RETURN __declspec(restrict)
# if _MSC_VER >= 1900 && !defined(__EDG__)
# define JEMALLOC_ALLOCATOR __declspec(allocator)
# else
# define JEMALLOC_ALLOCATOR
# endif
#elif defined(JEMALLOC_HAVE_ATTR)
# define JEMALLOC_ATTR(s) __attribute__((s))
# define JEMALLOC_ALIGNED(s) JEMALLOC_ATTR(aligned(s))
# ifdef JEMALLOC_HAVE_ATTR_ALLOC_SIZE
# define JEMALLOC_ALLOC_SIZE(s) JEMALLOC_ATTR(alloc_size(s))
# define JEMALLOC_ALLOC_SIZE2(s1, s2) JEMALLOC_ATTR(alloc_size(s1, s2))
# else
# define JEMALLOC_ALLOC_SIZE(s)
# define JEMALLOC_ALLOC_SIZE2(s1, s2)
# endif
# ifndef JEMALLOC_EXPORT
# define JEMALLOC_EXPORT JEMALLOC_ATTR(visibility("default"))
# endif
# ifdef JEMALLOC_HAVE_ATTR_FORMAT_GNU_PRINTF
# define JEMALLOC_FORMAT_PRINTF(s, i) JEMALLOC_ATTR(format(gnu_printf, s, i))
# elif defined(JEMALLOC_HAVE_ATTR_FORMAT_PRINTF)
# define JEMALLOC_FORMAT_PRINTF(s, i) JEMALLOC_ATTR(format(printf, s, i))
# else
# define JEMALLOC_FORMAT_PRINTF(s, i)
# endif
# define JEMALLOC_NOINLINE JEMALLOC_ATTR(noinline)
# define JEMALLOC_NOTHROW JEMALLOC_ATTR(nothrow)
# define JEMALLOC_SECTION(s) JEMALLOC_ATTR(section(s))
# define JEMALLOC_RESTRICT_RETURN
# define JEMALLOC_ALLOCATOR
#else
# define JEMALLOC_ATTR(s)
# define JEMALLOC_EXPORT
# define JEMALLOC_ALIGNED(s)
# define JEMALLOC_SECTION(s)
# define JEMALLOC_ALLOC_SIZE(s)
# define JEMALLOC_ALLOC_SIZE2(s1, s2)
# define JEMALLOC_EXPORT
# define JEMALLOC_FORMAT_PRINTF(s, i)
# define JEMALLOC_NOINLINE
# define JEMALLOC_NOTHROW
# define JEMALLOC_SECTION(s)
# define JEMALLOC_RESTRICT_RETURN
# define JEMALLOC_ALLOCATOR
#endif
/* This version of Jemalloc, modified for Redis, has the je_get_defrag_hint()
* function. */
#define JEMALLOC_FRAG_HINT
deps/jemalloc/include/jemalloc/jemalloc_mangle.sh
View file @
f63e81c2
#!/bin/sh
#!/bin/sh
-eu
public_symbols_txt
=
$1
symbol_prefix
=
$2
...
...
deps/jemalloc/include/jemalloc/jemalloc_protos.h.in
View file @
f63e81c2
...
...
@@ -7,52 +7,60 @@ extern JEMALLOC_EXPORT const char *@je_@malloc_conf;
extern JEMALLOC_EXPORT void (*@je_@malloc_message)(void *cbopaque,
const char *s);
JEMALLOC_EXPORT void *@je_@malloc(size_t size) JEMALLOC_ATTR(malloc);
JEMALLOC_EXPORT void *@je_@calloc(size_t num, size_t size)
JEMALLOC_ATTR(malloc);
JEMALLOC_EXPORT int @je_@posix_memalign(void **memptr, size_t alignment,
size_t size) JEMALLOC_ATTR(nonnull(1));
JEMALLOC_EXPORT void *@je_@aligned_alloc(size_t alignment, size_t size)
JEMALLOC_ATTR(malloc);
JEMALLOC_EXPORT void *@je_@realloc(void *ptr, size_t size);
JEMALLOC_EXPORT void @je_@free(void *ptr);
JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN
void JEMALLOC_NOTHROW *@je_@malloc(size_t size)
JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(1);
JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN
void JEMALLOC_NOTHROW *@je_@calloc(size_t num, size_t size)
JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE2(1, 2);
JEMALLOC_EXPORT int JEMALLOC_NOTHROW @je_@posix_memalign(void **memptr,
size_t alignment, size_t size) JEMALLOC_CXX_THROW JEMALLOC_ATTR(nonnull(1));
JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN
void JEMALLOC_NOTHROW *@je_@aligned_alloc(size_t alignment,
size_t size) JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc)
JEMALLOC_ALLOC_SIZE(2);
JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN
void JEMALLOC_NOTHROW *@je_@realloc(void *ptr, size_t size)
JEMALLOC_CXX_THROW JEMALLOC_ALLOC_SIZE(2);
JEMALLOC_EXPORT void JEMALLOC_NOTHROW @je_@free(void *ptr)
JEMALLOC_CXX_THROW;
JEMALLOC_EXPORT void *@je_@mallocx(size_t size, int flags);
JEMALLOC_EXPORT void *@je_@rallocx(void *ptr, size_t size, int flags);
JEMALLOC_EXPORT size_t @je_@xallocx(void *ptr, size_t size, size_t extra,
JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN
void JEMALLOC_NOTHROW *@je_@mallocx(size_t size, int flags)
JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(1);
JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN
void JEMALLOC_NOTHROW *@je_@rallocx(void *ptr, size_t size,
int flags) JEMALLOC_ALLOC_SIZE(2);
JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW @je_@xallocx(void *ptr, size_t size,
size_t extra, int flags);
JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW @je_@sallocx(const void *ptr,
int flags) JEMALLOC_ATTR(pure);
JEMALLOC_EXPORT void JEMALLOC_NOTHROW @je_@dallocx(void *ptr, int flags);
JEMALLOC_EXPORT void JEMALLOC_NOTHROW @je_@sdallocx(void *ptr, size_t size,
int flags);
JEMALLOC_EXPORT size_t @je_@sallocx(const void *ptr, int flags);
JEMALLOC_EXPORT void @je_@dallocx(void *ptr, int flags);
JEMALLOC_EXPORT size_t @je_@nallocx(size_t size, int flags);
JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW @je_@nallocx(size_t size, int flags)
JEMALLOC_ATTR(pure);
JEMALLOC_EXPORT int @je_@mallctl(const char *name, void *oldp,
size_t *oldlenp, void *newp, size_t newlen);
JEMALLOC_EXPORT int @je_@mallctlnametomib(const char *name, size_t *mibp,
size_t *miblenp);
JEMALLOC_EXPORT int @je_@mallctlbymib(const size_t *mib, size_t miblen,
JEMALLOC_EXPORT int JEMALLOC_NOTHROW @je_@mallctl(const char *name,
void *oldp, size_t *oldlenp, void *newp, size_t newlen);
JEMALLOC_EXPORT void @je_@malloc_stats_print(void (*write_cb)(void *,
const char *), void *@je_@cbopaque, const char *opts);
JEMALLOC_EXPORT size_t @je_@malloc_usable_size(
JEMALLOC_USABLE_SIZE_CONST void *ptr);
JEMALLOC_EXPORT int JEMALLOC_NOTHROW @je_@mallctlnametomib(const char *name,
size_t *mibp, size_t *miblenp);
JEMALLOC_EXPORT int JEMALLOC_NOTHROW @je_@mallctlbymib(const size_t *mib,
size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen);
JEMALLOC_EXPORT void JEMALLOC_NOTHROW @je_@malloc_stats_print(
void (*write_cb)(void *, const char *), void *@je_@cbopaque,
const char *opts);
JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW @je_@malloc_usable_size(
JEMALLOC_USABLE_SIZE_CONST void *ptr) JEMALLOC_CXX_THROW;
#ifdef JEMALLOC_OVERRIDE_MEMALIGN
JEMALLOC_EXPORT void * @je_@memalign(size_t alignment, size_t size)
JEMALLOC_ATTR(malloc);
JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN
void JEMALLOC_NOTHROW *@je_@memalign(size_t alignment, size_t size)
JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc);
#endif
#ifdef JEMALLOC_OVERRIDE_VALLOC
JEMALLOC_EXPORT void * @je_@valloc(size_t size) JEMALLOC_ATTR(malloc);
#endif
#ifdef JEMALLOC_EXPERIMENTAL
JEMALLOC_EXPORT int @je_@allocm(void **ptr, size_t *rsize, size_t size,
int flags) JEMALLOC_ATTR(nonnull(1));
JEMALLOC_EXPORT int @je_@rallocm(void **ptr, size_t *rsize, size_t size,
size_t extra, int flags) JEMALLOC_ATTR(nonnull(1));
JEMALLOC_EXPORT int @je_@sallocm(const void *ptr, size_t *rsize, int flags)
JEMALLOC_ATTR(nonnull(1));
JEMALLOC_EXPORT int @je_@dallocm(void *ptr, int flags)
JEMALLOC_ATTR(nonnull(1));
JEMALLOC_EXPORT int @je_@nallocm(size_t *rsize, size_t size, int flags);
JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN
void JEMALLOC_NOTHROW *@je_@valloc(size_t size) JEMALLOC_CXX_THROW
JEMALLOC_ATTR(malloc);
#endif
deps/jemalloc/include/jemalloc/jemalloc_typedefs.h.in
0 → 100644
View file @
f63e81c2
typedef struct extent_hooks_s extent_hooks_t;
/*
* void *
* extent_alloc(extent_hooks_t *extent_hooks, void *new_addr, size_t size,
* size_t alignment, bool *zero, bool *commit, unsigned arena_ind);
*/
typedef void *(extent_alloc_t)(extent_hooks_t *, void *, size_t, size_t, bool *,
bool *, unsigned);
/*
* bool
* extent_dalloc(extent_hooks_t *extent_hooks, void *addr, size_t size,
* bool committed, unsigned arena_ind);
*/
typedef bool (extent_dalloc_t)(extent_hooks_t *, void *, size_t, bool,
unsigned);
/*
* void
* extent_destroy(extent_hooks_t *extent_hooks, void *addr, size_t size,
* bool committed, unsigned arena_ind);
*/
typedef void (extent_destroy_t)(extent_hooks_t *, void *, size_t, bool,
unsigned);
/*
* bool
* extent_commit(extent_hooks_t *extent_hooks, void *addr, size_t size,
* size_t offset, size_t length, unsigned arena_ind);
*/
typedef bool (extent_commit_t)(extent_hooks_t *, void *, size_t, size_t, size_t,
unsigned);
/*
* bool
* extent_decommit(extent_hooks_t *extent_hooks, void *addr, size_t size,
* size_t offset, size_t length, unsigned arena_ind);
*/
typedef bool (extent_decommit_t)(extent_hooks_t *, void *, size_t, size_t,
size_t, unsigned);
/*
* bool
* extent_purge(extent_hooks_t *extent_hooks, void *addr, size_t size,
* size_t offset, size_t length, unsigned arena_ind);
*/
typedef bool (extent_purge_t)(extent_hooks_t *, void *, size_t, size_t, size_t,
unsigned);
/*
* bool
* extent_split(extent_hooks_t *extent_hooks, void *addr, size_t size,
* size_t size_a, size_t size_b, bool committed, unsigned arena_ind);
*/
typedef bool (extent_split_t)(extent_hooks_t *, void *, size_t, size_t, size_t,
bool, unsigned);
/*
* bool
* extent_merge(extent_hooks_t *extent_hooks, void *addr_a, size_t size_a,
* void *addr_b, size_t size_b, bool committed, unsigned arena_ind);
*/
typedef bool (extent_merge_t)(extent_hooks_t *, void *, size_t, void *, size_t,
bool, unsigned);
struct extent_hooks_s {
extent_alloc_t *alloc;
extent_dalloc_t *dalloc;
extent_destroy_t *destroy;
extent_commit_t *commit;
extent_decommit_t *decommit;
extent_purge_t *purge_lazy;
extent_purge_t *purge_forced;
extent_split_t *split;
extent_merge_t *merge;
};
deps/jemalloc/include/msvc_compat/stdbool.h
→
deps/jemalloc/include/msvc_compat/
C99/
stdbool.h
View file @
f63e81c2
...
...
@@ -5,7 +5,11 @@
/* MSVC doesn't define _Bool or bool in C, but does have BOOL */
/* Note this doesn't pass autoconf's test because (bool) 0.5 != true */
/* Clang-cl uses MSVC headers, so needs msvc_compat, but has _Bool as
* a built-in type. */
#ifndef __clang__
typedef
BOOL
_Bool
;
#endif
#define bool _Bool
#define true 1
...
...
deps/jemalloc/include/msvc_compat/stdint.h
→
deps/jemalloc/include/msvc_compat/
C99/
stdint.h
View file @
f63e81c2
File moved
deps/jemalloc/include/msvc_compat/inttypes.h
deleted
100644 → 0
View file @
eaeba1b2
// ISO C9x compliant inttypes.h for Microsoft Visual Studio
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
//
// Copyright (c) 2006 Alexander Chemeris
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. The name of the author may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _MSC_VER // [
#error "Use this header only with Microsoft Visual C++ compilers!"
#endif // _MSC_VER ]
#ifndef _MSC_INTTYPES_H_ // [
#define _MSC_INTTYPES_H_
#if _MSC_VER > 1000
#pragma once
#endif
#include "stdint.h"
// 7.8 Format conversion of integer types
typedef
struct
{
intmax_t
quot
;
intmax_t
rem
;
}
imaxdiv_t
;
// 7.8.1 Macros for format specifiers
#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198
#ifdef _WIN64
# define __PRI64_PREFIX "l"
# define __PRIPTR_PREFIX "l"
#else
# define __PRI64_PREFIX "ll"
# define __PRIPTR_PREFIX
#endif
// The fprintf macros for signed integers are:
#define PRId8 "d"
#define PRIi8 "i"
#define PRIdLEAST8 "d"
#define PRIiLEAST8 "i"
#define PRIdFAST8 "d"
#define PRIiFAST8 "i"
#define PRId16 "hd"
#define PRIi16 "hi"
#define PRIdLEAST16 "hd"
#define PRIiLEAST16 "hi"
#define PRIdFAST16 "hd"
#define PRIiFAST16 "hi"
#define PRId32 "d"
#define PRIi32 "i"
#define PRIdLEAST32 "d"
#define PRIiLEAST32 "i"
#define PRIdFAST32 "d"
#define PRIiFAST32 "i"
#define PRId64 __PRI64_PREFIX "d"
#define PRIi64 __PRI64_PREFIX "i"
#define PRIdLEAST64 __PRI64_PREFIX "d"
#define PRIiLEAST64 __PRI64_PREFIX "i"
#define PRIdFAST64 __PRI64_PREFIX "d"
#define PRIiFAST64 __PRI64_PREFIX "i"
#define PRIdMAX __PRI64_PREFIX "d"
#define PRIiMAX __PRI64_PREFIX "i"
#define PRIdPTR __PRIPTR_PREFIX "d"
#define PRIiPTR __PRIPTR_PREFIX "i"
// The fprintf macros for unsigned integers are:
#define PRIo8 "o"
#define PRIu8 "u"
#define PRIx8 "x"
#define PRIX8 "X"
#define PRIoLEAST8 "o"
#define PRIuLEAST8 "u"
#define PRIxLEAST8 "x"
#define PRIXLEAST8 "X"
#define PRIoFAST8 "o"
#define PRIuFAST8 "u"
#define PRIxFAST8 "x"
#define PRIXFAST8 "X"
#define PRIo16 "ho"
#define PRIu16 "hu"
#define PRIx16 "hx"
#define PRIX16 "hX"
#define PRIoLEAST16 "ho"
#define PRIuLEAST16 "hu"
#define PRIxLEAST16 "hx"
#define PRIXLEAST16 "hX"
#define PRIoFAST16 "ho"
#define PRIuFAST16 "hu"
#define PRIxFAST16 "hx"
#define PRIXFAST16 "hX"
#define PRIo32 "o"
#define PRIu32 "u"
#define PRIx32 "x"
#define PRIX32 "X"
#define PRIoLEAST32 "o"
#define PRIuLEAST32 "u"
#define PRIxLEAST32 "x"
#define PRIXLEAST32 "X"
#define PRIoFAST32 "o"
#define PRIuFAST32 "u"
#define PRIxFAST32 "x"
#define PRIXFAST32 "X"
#define PRIo64 __PRI64_PREFIX "o"
#define PRIu64 __PRI64_PREFIX "u"
#define PRIx64 __PRI64_PREFIX "x"
#define PRIX64 __PRI64_PREFIX "X"
#define PRIoLEAST64 __PRI64_PREFIX "o"
#define PRIuLEAST64 __PRI64_PREFIX "u"
#define PRIxLEAST64 __PRI64_PREFIX "x"
#define PRIXLEAST64 __PRI64_PREFIX "X"
#define PRIoFAST64 __PRI64_PREFIX "o"
#define PRIuFAST64 __PRI64_PREFIX "u"
#define PRIxFAST64 __PRI64_PREFIX "x"
#define PRIXFAST64 __PRI64_PREFIX "X"
#define PRIoMAX __PRI64_PREFIX "o"
#define PRIuMAX __PRI64_PREFIX "u"
#define PRIxMAX __PRI64_PREFIX "x"
#define PRIXMAX __PRI64_PREFIX "X"
#define PRIoPTR __PRIPTR_PREFIX "o"
#define PRIuPTR __PRIPTR_PREFIX "u"
#define PRIxPTR __PRIPTR_PREFIX "x"
#define PRIXPTR __PRIPTR_PREFIX "X"
// The fscanf macros for signed integers are:
#define SCNd8 "d"
#define SCNi8 "i"
#define SCNdLEAST8 "d"
#define SCNiLEAST8 "i"
#define SCNdFAST8 "d"
#define SCNiFAST8 "i"
#define SCNd16 "hd"
#define SCNi16 "hi"
#define SCNdLEAST16 "hd"
#define SCNiLEAST16 "hi"
#define SCNdFAST16 "hd"
#define SCNiFAST16 "hi"
#define SCNd32 "ld"
#define SCNi32 "li"
#define SCNdLEAST32 "ld"
#define SCNiLEAST32 "li"
#define SCNdFAST32 "ld"
#define SCNiFAST32 "li"
#define SCNd64 "I64d"
#define SCNi64 "I64i"
#define SCNdLEAST64 "I64d"
#define SCNiLEAST64 "I64i"
#define SCNdFAST64 "I64d"
#define SCNiFAST64 "I64i"
#define SCNdMAX "I64d"
#define SCNiMAX "I64i"
#ifdef _WIN64 // [
# define SCNdPTR "I64d"
# define SCNiPTR "I64i"
#else // _WIN64 ][
# define SCNdPTR "ld"
# define SCNiPTR "li"
#endif // _WIN64 ]
// The fscanf macros for unsigned integers are:
#define SCNo8 "o"
#define SCNu8 "u"
#define SCNx8 "x"
#define SCNX8 "X"
#define SCNoLEAST8 "o"
#define SCNuLEAST8 "u"
#define SCNxLEAST8 "x"
#define SCNXLEAST8 "X"
#define SCNoFAST8 "o"
#define SCNuFAST8 "u"
#define SCNxFAST8 "x"
#define SCNXFAST8 "X"
#define SCNo16 "ho"
#define SCNu16 "hu"
#define SCNx16 "hx"
#define SCNX16 "hX"
#define SCNoLEAST16 "ho"
#define SCNuLEAST16 "hu"
#define SCNxLEAST16 "hx"
#define SCNXLEAST16 "hX"
#define SCNoFAST16 "ho"
#define SCNuFAST16 "hu"
#define SCNxFAST16 "hx"
#define SCNXFAST16 "hX"
#define SCNo32 "lo"
#define SCNu32 "lu"
#define SCNx32 "lx"
#define SCNX32 "lX"
#define SCNoLEAST32 "lo"
#define SCNuLEAST32 "lu"
#define SCNxLEAST32 "lx"
#define SCNXLEAST32 "lX"
#define SCNoFAST32 "lo"
#define SCNuFAST32 "lu"
#define SCNxFAST32 "lx"
#define SCNXFAST32 "lX"
#define SCNo64 "I64o"
#define SCNu64 "I64u"
#define SCNx64 "I64x"
#define SCNX64 "I64X"
#define SCNoLEAST64 "I64o"
#define SCNuLEAST64 "I64u"
#define SCNxLEAST64 "I64x"
#define SCNXLEAST64 "I64X"
#define SCNoFAST64 "I64o"
#define SCNuFAST64 "I64u"
#define SCNxFAST64 "I64x"
#define SCNXFAST64 "I64X"
#define SCNoMAX "I64o"
#define SCNuMAX "I64u"
#define SCNxMAX "I64x"
#define SCNXMAX "I64X"
#ifdef _WIN64 // [
# define SCNoPTR "I64o"
# define SCNuPTR "I64u"
# define SCNxPTR "I64x"
# define SCNXPTR "I64X"
#else // _WIN64 ][
# define SCNoPTR "lo"
# define SCNuPTR "lu"
# define SCNxPTR "lx"
# define SCNXPTR "lX"
#endif // _WIN64 ]
#endif // __STDC_FORMAT_MACROS ]
// 7.8.2 Functions for greatest-width integer types
// 7.8.2.1 The imaxabs function
#define imaxabs _abs64
// 7.8.2.2 The imaxdiv function
// This is modified version of div() function from Microsoft's div.c found
// in %MSVC.NET%\crt\src\div.c
#ifdef STATIC_IMAXDIV // [
static
#else // STATIC_IMAXDIV ][
_inline
#endif // STATIC_IMAXDIV ]
imaxdiv_t
__cdecl
imaxdiv
(
intmax_t
numer
,
intmax_t
denom
)
{
imaxdiv_t
result
;
result
.
quot
=
numer
/
denom
;
result
.
rem
=
numer
%
denom
;
if
(
numer
<
0
&&
result
.
rem
>
0
)
{
// did division wrong; must fix up
++
result
.
quot
;
result
.
rem
-=
denom
;
}
return
result
;
}
// 7.8.2.3 The strtoimax and strtoumax functions
#define strtoimax _strtoi64
#define strtoumax _strtoui64
// 7.8.2.4 The wcstoimax and wcstoumax functions
#define wcstoimax _wcstoi64
#define wcstoumax _wcstoui64
#endif // _MSC_INTTYPES_H_ ]
deps/jemalloc/include/msvc_compat/strings.h
View file @
f63e81c2
...
...
@@ -3,21 +3,56 @@
/* MSVC doesn't define ffs/ffsl. This dummy strings.h header is provided
* for both */
#i
nclude <intrin.h>
#
pragma intrinsic(_BitScanForward)
static
__forceinline
int
ffsl
(
long
x
)
{
#i
fdef _MSC_VER
#
include <intrin.h>
# pragma intrinsic(_BitScanForward
)
static
__forceinline
int
ffsl
(
long
x
)
{
unsigned
long
i
;
if
(
_BitScanForward
(
&
i
,
x
))
return
(
i
+
1
);
return
(
0
);
if
(
_BitScanForward
(
&
i
,
x
))
{
return
i
+
1
;
}
return
0
;
}
static
__forceinline
int
ffs
(
int
x
)
{
static
__forceinline
int
ffs
(
int
x
)
{
return
ffsl
(
x
);
}
# ifdef _M_X64
# pragma intrinsic(_BitScanForward64)
# endif
static
__forceinline
int
ffsll
(
unsigned
__int64
x
)
{
unsigned
long
i
;
#ifdef _M_X64
if
(
_BitScanForward64
(
&
i
,
x
))
{
return
i
+
1
;
}
return
0
;
#else
// Fallback for 32-bit build where 64-bit version not available
// assuming little endian
union
{
unsigned
__int64
ll
;
unsigned
long
l
[
2
];
}
s
;
return
(
ffsl
(
x
));
s
.
ll
=
x
;
if
(
_BitScanForward
(
&
i
,
s
.
l
[
0
]))
{
return
i
+
1
;
}
else
if
(
_BitScanForward
(
&
i
,
s
.
l
[
1
]))
{
return
i
+
33
;
}
return
0
;
#endif
}
#else
# define ffsll(x) __builtin_ffsll(x)
# define ffsl(x) __builtin_ffsl(x)
# define ffs(x) __builtin_ffs(x)
#endif
#endif
/* strings_h */
deps/jemalloc/include/msvc_compat/windows_extra.h
0 → 100644
View file @
f63e81c2
#ifndef MSVC_COMPAT_WINDOWS_EXTRA_H
#define MSVC_COMPAT_WINDOWS_EXTRA_H
#include <errno.h>
#endif
/* MSVC_COMPAT_WINDOWS_EXTRA_H */
Prev
1
…
5
6
7
8
9
10
11
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment