Do not (recursively) allocate within tsd_fetch().
Refactor tsd so that tsdn_fetch() does not trigger allocation, since allocation could cause infinite recursion. This resolves #458.
This commit is contained in:
parent
e2bcf037d4
commit
962a2979e3
@ -64,13 +64,13 @@ struct ckh_s {
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
#ifdef JEMALLOC_H_EXTERNS
|
#ifdef JEMALLOC_H_EXTERNS
|
||||||
|
|
||||||
bool ckh_new(tsdn_t *tsdn, ckh_t *ckh, size_t minitems, ckh_hash_t *hash,
|
bool ckh_new(tsd_t *tsd, ckh_t *ckh, size_t minitems, ckh_hash_t *hash,
|
||||||
ckh_keycomp_t *keycomp);
|
ckh_keycomp_t *keycomp);
|
||||||
void ckh_delete(tsdn_t *tsdn, ckh_t *ckh);
|
void ckh_delete(tsd_t *tsd, ckh_t *ckh);
|
||||||
size_t ckh_count(ckh_t *ckh);
|
size_t ckh_count(ckh_t *ckh);
|
||||||
bool ckh_iter(ckh_t *ckh, size_t *tabind, void **key, void **data);
|
bool ckh_iter(ckh_t *ckh, size_t *tabind, void **key, void **data);
|
||||||
bool ckh_insert(tsdn_t *tsdn, ckh_t *ckh, const void *key, const void *data);
|
bool ckh_insert(tsd_t *tsd, ckh_t *ckh, const void *key, const void *data);
|
||||||
bool ckh_remove(tsdn_t *tsdn, ckh_t *ckh, const void *searchkey, void **key,
|
bool ckh_remove(tsd_t *tsd, ckh_t *ckh, const void *searchkey, void **key,
|
||||||
void **data);
|
void **data);
|
||||||
bool ckh_search(ckh_t *ckh, const void *searchkey, void **key, void **data);
|
bool ckh_search(ckh_t *ckh, const void *searchkey, void **key, void **data);
|
||||||
void ckh_string_hash(const void *key, size_t r_hash[2]);
|
void ckh_string_hash(const void *key, size_t r_hash[2]);
|
||||||
|
@ -479,6 +479,7 @@ extern size_t const index2size_tab[NSIZES];
|
|||||||
*/
|
*/
|
||||||
extern uint8_t const size2index_tab[];
|
extern uint8_t const size2index_tab[];
|
||||||
|
|
||||||
|
arena_t *a0get(void);
|
||||||
void *a0malloc(size_t size);
|
void *a0malloc(size_t size);
|
||||||
void a0dalloc(void *ptr);
|
void a0dalloc(void *ptr);
|
||||||
void *bootstrap_malloc(size_t size);
|
void *bootstrap_malloc(size_t size);
|
||||||
@ -574,7 +575,7 @@ size_t s2u(size_t size);
|
|||||||
size_t sa2u(size_t size, size_t alignment);
|
size_t sa2u(size_t size, size_t alignment);
|
||||||
arena_t *arena_choose_impl(tsd_t *tsd, arena_t *arena, bool internal);
|
arena_t *arena_choose_impl(tsd_t *tsd, arena_t *arena, bool internal);
|
||||||
arena_t *arena_choose(tsd_t *tsd, arena_t *arena);
|
arena_t *arena_choose(tsd_t *tsd, arena_t *arena);
|
||||||
arena_t *arena_ichoose(tsdn_t *tsdn, arena_t *arena);
|
arena_t *arena_ichoose(tsd_t *tsd, arena_t *arena);
|
||||||
arena_tdata_t *arena_tdata_get(tsd_t *tsd, unsigned ind,
|
arena_tdata_t *arena_tdata_get(tsd_t *tsd, unsigned ind,
|
||||||
bool refresh_if_missing);
|
bool refresh_if_missing);
|
||||||
arena_t *arena_get(tsdn_t *tsdn, unsigned ind, bool init_if_missing);
|
arena_t *arena_get(tsdn_t *tsdn, unsigned ind, bool init_if_missing);
|
||||||
@ -912,14 +913,10 @@ arena_choose(tsd_t *tsd, arena_t *arena)
|
|||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_INLINE arena_t *
|
JEMALLOC_INLINE arena_t *
|
||||||
arena_ichoose(tsdn_t *tsdn, arena_t *arena)
|
arena_ichoose(tsd_t *tsd, arena_t *arena)
|
||||||
{
|
{
|
||||||
|
|
||||||
assert(!tsdn_null(tsdn) || arena != NULL);
|
return (arena_choose_impl(tsd, arena, true));
|
||||||
|
|
||||||
if (!tsdn_null(tsdn))
|
|
||||||
return (arena_choose_impl(tsdn_tsd(tsdn), NULL, true));
|
|
||||||
return (arena);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_INLINE arena_tdata_t *
|
JEMALLOC_INLINE arena_tdata_t *
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
a0dalloc
|
a0dalloc
|
||||||
|
a0get
|
||||||
a0malloc
|
a0malloc
|
||||||
arena_aalloc
|
arena_aalloc
|
||||||
arena_alloc_junk_small
|
arena_alloc_junk_small
|
||||||
@ -545,7 +546,9 @@ tsd_booted_get
|
|||||||
tsd_cleanup
|
tsd_cleanup
|
||||||
tsd_cleanup_wrapper
|
tsd_cleanup_wrapper
|
||||||
tsd_fetch
|
tsd_fetch
|
||||||
|
tsd_fetch_impl
|
||||||
tsd_get
|
tsd_get
|
||||||
|
tsd_get_allocates
|
||||||
tsd_iarena_get
|
tsd_iarena_get
|
||||||
tsd_iarena_set
|
tsd_iarena_set
|
||||||
tsd_iarenap_get
|
tsd_iarenap_get
|
||||||
|
@ -299,9 +299,9 @@ extern prof_dump_header_t *prof_dump_header;
|
|||||||
void prof_idump(tsdn_t *tsdn);
|
void prof_idump(tsdn_t *tsdn);
|
||||||
bool prof_mdump(tsd_t *tsd, const char *filename);
|
bool prof_mdump(tsd_t *tsd, const char *filename);
|
||||||
void prof_gdump(tsdn_t *tsdn);
|
void prof_gdump(tsdn_t *tsdn);
|
||||||
prof_tdata_t *prof_tdata_init(tsdn_t *tsdn);
|
prof_tdata_t *prof_tdata_init(tsd_t *tsd);
|
||||||
prof_tdata_t *prof_tdata_reinit(tsd_t *tsd, prof_tdata_t *tdata);
|
prof_tdata_t *prof_tdata_reinit(tsd_t *tsd, prof_tdata_t *tdata);
|
||||||
void prof_reset(tsdn_t *tsdn, size_t lg_sample);
|
void prof_reset(tsd_t *tsd, size_t lg_sample);
|
||||||
void prof_tdata_cleanup(tsd_t *tsd);
|
void prof_tdata_cleanup(tsd_t *tsd);
|
||||||
bool prof_active_get(tsdn_t *tsdn);
|
bool prof_active_get(tsdn_t *tsdn);
|
||||||
bool prof_active_set(tsdn_t *tsdn, bool active);
|
bool prof_active_set(tsdn_t *tsdn, bool active);
|
||||||
@ -315,7 +315,7 @@ bool prof_gdump_get(tsdn_t *tsdn);
|
|||||||
bool prof_gdump_set(tsdn_t *tsdn, bool active);
|
bool prof_gdump_set(tsdn_t *tsdn, bool active);
|
||||||
void prof_boot0(void);
|
void prof_boot0(void);
|
||||||
void prof_boot1(void);
|
void prof_boot1(void);
|
||||||
bool prof_boot2(tsdn_t *tsdn);
|
bool prof_boot2(tsd_t *tsd);
|
||||||
void prof_prefork0(tsdn_t *tsdn);
|
void prof_prefork0(tsdn_t *tsdn);
|
||||||
void prof_prefork1(tsdn_t *tsdn);
|
void prof_prefork1(tsdn_t *tsdn);
|
||||||
void prof_postfork_parent(tsdn_t *tsdn);
|
void prof_postfork_parent(tsdn_t *tsdn);
|
||||||
@ -384,7 +384,7 @@ prof_tdata_get(tsd_t *tsd, bool create)
|
|||||||
if (create) {
|
if (create) {
|
||||||
if (unlikely(tdata == NULL)) {
|
if (unlikely(tdata == NULL)) {
|
||||||
if (tsd_nominal(tsd)) {
|
if (tsd_nominal(tsd)) {
|
||||||
tdata = prof_tdata_init(tsd_tsdn(tsd));
|
tdata = prof_tdata_init(tsd);
|
||||||
tsd_prof_tdata_set(tsd, tdata);
|
tsd_prof_tdata_set(tsd, tdata);
|
||||||
}
|
}
|
||||||
} else if (unlikely(tdata->expired)) {
|
} else if (unlikely(tdata->expired)) {
|
||||||
|
@ -145,7 +145,7 @@ tcache_t *tcache_create(tsdn_t *tsdn, arena_t *arena);
|
|||||||
void tcache_cleanup(tsd_t *tsd);
|
void tcache_cleanup(tsd_t *tsd);
|
||||||
void tcache_enabled_cleanup(tsd_t *tsd);
|
void tcache_enabled_cleanup(tsd_t *tsd);
|
||||||
void tcache_stats_merge(tsdn_t *tsdn, tcache_t *tcache, arena_t *arena);
|
void tcache_stats_merge(tsdn_t *tsdn, tcache_t *tcache, arena_t *arena);
|
||||||
bool tcaches_create(tsdn_t *tsdn, unsigned *r_ind);
|
bool tcaches_create(tsd_t *tsd, unsigned *r_ind);
|
||||||
void tcaches_flush(tsd_t *tsd, unsigned ind);
|
void tcaches_flush(tsd_t *tsd, unsigned ind);
|
||||||
void tcaches_destroy(tsd_t *tsd, unsigned ind);
|
void tcaches_destroy(tsd_t *tsd, unsigned ind);
|
||||||
bool tcache_boot(tsdn_t *tsdn);
|
bool tcache_boot(tsdn_t *tsdn);
|
||||||
|
@ -48,7 +48,7 @@ typedef enum {
|
|||||||
*
|
*
|
||||||
* bool example_tsd_boot(void) {...}
|
* bool example_tsd_boot(void) {...}
|
||||||
* bool example_tsd_booted_get(void) {...}
|
* bool example_tsd_booted_get(void) {...}
|
||||||
* example_t *example_tsd_get() {...}
|
* example_t *example_tsd_get(bool init) {...}
|
||||||
* void example_tsd_set(example_t *val) {...}
|
* void example_tsd_set(example_t *val) {...}
|
||||||
*
|
*
|
||||||
* Note that all of the functions deal in terms of (a_type *) rather than
|
* Note that all of the functions deal in terms of (a_type *) rather than
|
||||||
@ -105,7 +105,7 @@ a_name##tsd_boot(void); \
|
|||||||
a_attr bool \
|
a_attr bool \
|
||||||
a_name##tsd_booted_get(void); \
|
a_name##tsd_booted_get(void); \
|
||||||
a_attr a_type * \
|
a_attr a_type * \
|
||||||
a_name##tsd_get(void); \
|
a_name##tsd_get(bool init); \
|
||||||
a_attr void \
|
a_attr void \
|
||||||
a_name##tsd_set(a_type *val);
|
a_name##tsd_set(a_type *val);
|
||||||
|
|
||||||
@ -213,9 +213,15 @@ a_name##tsd_booted_get(void) \
|
|||||||
\
|
\
|
||||||
return (a_name##tsd_booted); \
|
return (a_name##tsd_booted); \
|
||||||
} \
|
} \
|
||||||
|
a_attr bool \
|
||||||
|
a_name##tsd_get_allocates(void) \
|
||||||
|
{ \
|
||||||
|
\
|
||||||
|
return (false); \
|
||||||
|
} \
|
||||||
/* Get/set. */ \
|
/* Get/set. */ \
|
||||||
a_attr a_type * \
|
a_attr a_type * \
|
||||||
a_name##tsd_get(void) \
|
a_name##tsd_get(bool init) \
|
||||||
{ \
|
{ \
|
||||||
\
|
\
|
||||||
assert(a_name##tsd_booted); \
|
assert(a_name##tsd_booted); \
|
||||||
@ -264,9 +270,15 @@ a_name##tsd_booted_get(void) \
|
|||||||
\
|
\
|
||||||
return (a_name##tsd_booted); \
|
return (a_name##tsd_booted); \
|
||||||
} \
|
} \
|
||||||
|
a_attr bool \
|
||||||
|
a_name##tsd_get_allocates(void) \
|
||||||
|
{ \
|
||||||
|
\
|
||||||
|
return (false); \
|
||||||
|
} \
|
||||||
/* Get/set. */ \
|
/* Get/set. */ \
|
||||||
a_attr a_type * \
|
a_attr a_type * \
|
||||||
a_name##tsd_get(void) \
|
a_name##tsd_get(bool init) \
|
||||||
{ \
|
{ \
|
||||||
\
|
\
|
||||||
assert(a_name##tsd_booted); \
|
assert(a_name##tsd_booted); \
|
||||||
@ -325,14 +337,14 @@ a_name##tsd_wrapper_set(a_name##tsd_wrapper_t *wrapper) \
|
|||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
a_attr a_name##tsd_wrapper_t * \
|
a_attr a_name##tsd_wrapper_t * \
|
||||||
a_name##tsd_wrapper_get(void) \
|
a_name##tsd_wrapper_get(bool init) \
|
||||||
{ \
|
{ \
|
||||||
DWORD error = GetLastError(); \
|
DWORD error = GetLastError(); \
|
||||||
a_name##tsd_wrapper_t *wrapper = (a_name##tsd_wrapper_t *) \
|
a_name##tsd_wrapper_t *wrapper = (a_name##tsd_wrapper_t *) \
|
||||||
TlsGetValue(a_name##tsd_tsd); \
|
TlsGetValue(a_name##tsd_tsd); \
|
||||||
SetLastError(error); \
|
SetLastError(error); \
|
||||||
\
|
\
|
||||||
if (unlikely(wrapper == NULL)) { \
|
if (init && unlikely(wrapper == NULL)) { \
|
||||||
wrapper = (a_name##tsd_wrapper_t *) \
|
wrapper = (a_name##tsd_wrapper_t *) \
|
||||||
malloc_tsd_malloc(sizeof(a_name##tsd_wrapper_t)); \
|
malloc_tsd_malloc(sizeof(a_name##tsd_wrapper_t)); \
|
||||||
if (wrapper == NULL) { \
|
if (wrapper == NULL) { \
|
||||||
@ -392,14 +404,22 @@ a_name##tsd_booted_get(void) \
|
|||||||
\
|
\
|
||||||
return (a_name##tsd_booted); \
|
return (a_name##tsd_booted); \
|
||||||
} \
|
} \
|
||||||
|
a_attr bool \
|
||||||
|
a_name##tsd_get_allocates(void) \
|
||||||
|
{ \
|
||||||
|
\
|
||||||
|
return (true); \
|
||||||
|
} \
|
||||||
/* Get/set. */ \
|
/* Get/set. */ \
|
||||||
a_attr a_type * \
|
a_attr a_type * \
|
||||||
a_name##tsd_get(void) \
|
a_name##tsd_get(bool init) \
|
||||||
{ \
|
{ \
|
||||||
a_name##tsd_wrapper_t *wrapper; \
|
a_name##tsd_wrapper_t *wrapper; \
|
||||||
\
|
\
|
||||||
assert(a_name##tsd_booted); \
|
assert(a_name##tsd_booted); \
|
||||||
wrapper = a_name##tsd_wrapper_get(); \
|
wrapper = a_name##tsd_wrapper_get(init); \
|
||||||
|
if (a_name##tsd_get_allocates() && !init && wrapper == NULL) \
|
||||||
|
return (NULL); \
|
||||||
return (&wrapper->val); \
|
return (&wrapper->val); \
|
||||||
} \
|
} \
|
||||||
a_attr void \
|
a_attr void \
|
||||||
@ -408,7 +428,7 @@ a_name##tsd_set(a_type *val) \
|
|||||||
a_name##tsd_wrapper_t *wrapper; \
|
a_name##tsd_wrapper_t *wrapper; \
|
||||||
\
|
\
|
||||||
assert(a_name##tsd_booted); \
|
assert(a_name##tsd_booted); \
|
||||||
wrapper = a_name##tsd_wrapper_get(); \
|
wrapper = a_name##tsd_wrapper_get(true); \
|
||||||
wrapper->val = *(val); \
|
wrapper->val = *(val); \
|
||||||
if (a_cleanup != malloc_tsd_no_cleanup) \
|
if (a_cleanup != malloc_tsd_no_cleanup) \
|
||||||
wrapper->initialized = true; \
|
wrapper->initialized = true; \
|
||||||
@ -452,12 +472,12 @@ a_name##tsd_wrapper_set(a_name##tsd_wrapper_t *wrapper) \
|
|||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
a_attr a_name##tsd_wrapper_t * \
|
a_attr a_name##tsd_wrapper_t * \
|
||||||
a_name##tsd_wrapper_get(void) \
|
a_name##tsd_wrapper_get(bool init) \
|
||||||
{ \
|
{ \
|
||||||
a_name##tsd_wrapper_t *wrapper = (a_name##tsd_wrapper_t *) \
|
a_name##tsd_wrapper_t *wrapper = (a_name##tsd_wrapper_t *) \
|
||||||
pthread_getspecific(a_name##tsd_tsd); \
|
pthread_getspecific(a_name##tsd_tsd); \
|
||||||
\
|
\
|
||||||
if (unlikely(wrapper == NULL)) { \
|
if (init && unlikely(wrapper == NULL)) { \
|
||||||
tsd_init_block_t block; \
|
tsd_init_block_t block; \
|
||||||
wrapper = tsd_init_check_recursion( \
|
wrapper = tsd_init_check_recursion( \
|
||||||
&a_name##tsd_init_head, &block); \
|
&a_name##tsd_init_head, &block); \
|
||||||
@ -520,14 +540,22 @@ a_name##tsd_booted_get(void) \
|
|||||||
\
|
\
|
||||||
return (a_name##tsd_booted); \
|
return (a_name##tsd_booted); \
|
||||||
} \
|
} \
|
||||||
|
a_attr bool \
|
||||||
|
a_name##tsd_get_allocates(void) \
|
||||||
|
{ \
|
||||||
|
\
|
||||||
|
return (true); \
|
||||||
|
} \
|
||||||
/* Get/set. */ \
|
/* Get/set. */ \
|
||||||
a_attr a_type * \
|
a_attr a_type * \
|
||||||
a_name##tsd_get(void) \
|
a_name##tsd_get(bool init) \
|
||||||
{ \
|
{ \
|
||||||
a_name##tsd_wrapper_t *wrapper; \
|
a_name##tsd_wrapper_t *wrapper; \
|
||||||
\
|
\
|
||||||
assert(a_name##tsd_booted); \
|
assert(a_name##tsd_booted); \
|
||||||
wrapper = a_name##tsd_wrapper_get(); \
|
wrapper = a_name##tsd_wrapper_get(init); \
|
||||||
|
if (a_name##tsd_get_allocates() && !init && wrapper == NULL) \
|
||||||
|
return (NULL); \
|
||||||
return (&wrapper->val); \
|
return (&wrapper->val); \
|
||||||
} \
|
} \
|
||||||
a_attr void \
|
a_attr void \
|
||||||
@ -536,7 +564,7 @@ a_name##tsd_set(a_type *val) \
|
|||||||
a_name##tsd_wrapper_t *wrapper; \
|
a_name##tsd_wrapper_t *wrapper; \
|
||||||
\
|
\
|
||||||
assert(a_name##tsd_booted); \
|
assert(a_name##tsd_booted); \
|
||||||
wrapper = a_name##tsd_wrapper_get(); \
|
wrapper = a_name##tsd_wrapper_get(true); \
|
||||||
wrapper->val = *(val); \
|
wrapper->val = *(val); \
|
||||||
if (a_cleanup != malloc_tsd_no_cleanup) \
|
if (a_cleanup != malloc_tsd_no_cleanup) \
|
||||||
wrapper->initialized = true; \
|
wrapper->initialized = true; \
|
||||||
@ -639,6 +667,7 @@ void tsd_cleanup(void *arg);
|
|||||||
#ifndef JEMALLOC_ENABLE_INLINE
|
#ifndef JEMALLOC_ENABLE_INLINE
|
||||||
malloc_tsd_protos(JEMALLOC_ATTR(unused), , tsd_t)
|
malloc_tsd_protos(JEMALLOC_ATTR(unused), , tsd_t)
|
||||||
|
|
||||||
|
tsd_t *tsd_fetch_impl(bool init);
|
||||||
tsd_t *tsd_fetch(void);
|
tsd_t *tsd_fetch(void);
|
||||||
tsdn_t *tsd_tsdn(tsd_t *tsd);
|
tsdn_t *tsd_tsdn(tsd_t *tsd);
|
||||||
bool tsd_nominal(tsd_t *tsd);
|
bool tsd_nominal(tsd_t *tsd);
|
||||||
@ -658,9 +687,13 @@ malloc_tsd_externs(, tsd_t)
|
|||||||
malloc_tsd_funcs(JEMALLOC_ALWAYS_INLINE, , tsd_t, tsd_initializer, tsd_cleanup)
|
malloc_tsd_funcs(JEMALLOC_ALWAYS_INLINE, , tsd_t, tsd_initializer, tsd_cleanup)
|
||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE tsd_t *
|
JEMALLOC_ALWAYS_INLINE tsd_t *
|
||||||
tsd_fetch(void)
|
tsd_fetch_impl(bool init)
|
||||||
{
|
{
|
||||||
tsd_t *tsd = tsd_get();
|
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)) {
|
if (unlikely(tsd->state != tsd_state_nominal)) {
|
||||||
if (tsd->state == tsd_state_uninitialized) {
|
if (tsd->state == tsd_state_uninitialized) {
|
||||||
@ -677,6 +710,13 @@ tsd_fetch(void)
|
|||||||
return (tsd);
|
return (tsd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JEMALLOC_ALWAYS_INLINE tsd_t *
|
||||||
|
tsd_fetch(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (tsd_fetch_impl(true));
|
||||||
|
}
|
||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE tsdn_t *
|
JEMALLOC_ALWAYS_INLINE tsdn_t *
|
||||||
tsd_tsdn(tsd_t *tsd)
|
tsd_tsdn(tsd_t *tsd)
|
||||||
{
|
{
|
||||||
@ -723,7 +763,7 @@ tsdn_fetch(void)
|
|||||||
if (!tsd_booted_get())
|
if (!tsd_booted_get())
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
return (tsd_tsdn(tsd_fetch()));
|
return (tsd_tsdn(tsd_fetch_impl(false)));
|
||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE bool
|
JEMALLOC_ALWAYS_INLINE bool
|
||||||
|
42
src/ckh.c
42
src/ckh.c
@ -40,8 +40,8 @@
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* Function prototypes for non-inline static functions. */
|
/* Function prototypes for non-inline static functions. */
|
||||||
|
|
||||||
static bool ckh_grow(tsdn_t *tsdn, ckh_t *ckh);
|
static bool ckh_grow(tsd_t *tsd, ckh_t *ckh);
|
||||||
static void ckh_shrink(tsdn_t *tsdn, ckh_t *ckh);
|
static void ckh_shrink(tsd_t *tsd, ckh_t *ckh);
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
@ -244,7 +244,7 @@ ckh_rebuild(ckh_t *ckh, ckhc_t *aTab)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
ckh_grow(tsdn_t *tsdn, ckh_t *ckh)
|
ckh_grow(tsd_t *tsd, ckh_t *ckh)
|
||||||
{
|
{
|
||||||
bool ret;
|
bool ret;
|
||||||
ckhc_t *tab, *ttab;
|
ckhc_t *tab, *ttab;
|
||||||
@ -270,8 +270,8 @@ ckh_grow(tsdn_t *tsdn, ckh_t *ckh)
|
|||||||
ret = true;
|
ret = true;
|
||||||
goto label_return;
|
goto label_return;
|
||||||
}
|
}
|
||||||
tab = (ckhc_t *)ipallocztm(tsdn, usize, CACHELINE, true, NULL,
|
tab = (ckhc_t *)ipallocztm(tsd_tsdn(tsd), usize, CACHELINE,
|
||||||
true, arena_ichoose(tsdn, NULL));
|
true, NULL, true, arena_ichoose(tsd, NULL));
|
||||||
if (tab == NULL) {
|
if (tab == NULL) {
|
||||||
ret = true;
|
ret = true;
|
||||||
goto label_return;
|
goto label_return;
|
||||||
@ -283,12 +283,12 @@ ckh_grow(tsdn_t *tsdn, ckh_t *ckh)
|
|||||||
ckh->lg_curbuckets = lg_curcells - LG_CKH_BUCKET_CELLS;
|
ckh->lg_curbuckets = lg_curcells - LG_CKH_BUCKET_CELLS;
|
||||||
|
|
||||||
if (!ckh_rebuild(ckh, tab)) {
|
if (!ckh_rebuild(ckh, tab)) {
|
||||||
idalloctm(tsdn, tab, NULL, true, true);
|
idalloctm(tsd_tsdn(tsd), tab, NULL, true, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Rebuilding failed, so back out partially rebuilt table. */
|
/* Rebuilding failed, so back out partially rebuilt table. */
|
||||||
idalloctm(tsdn, ckh->tab, NULL, true, true);
|
idalloctm(tsd_tsdn(tsd), ckh->tab, NULL, true, true);
|
||||||
ckh->tab = tab;
|
ckh->tab = tab;
|
||||||
ckh->lg_curbuckets = lg_prevbuckets;
|
ckh->lg_curbuckets = lg_prevbuckets;
|
||||||
}
|
}
|
||||||
@ -299,7 +299,7 @@ label_return:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ckh_shrink(tsdn_t *tsdn, ckh_t *ckh)
|
ckh_shrink(tsd_t *tsd, ckh_t *ckh)
|
||||||
{
|
{
|
||||||
ckhc_t *tab, *ttab;
|
ckhc_t *tab, *ttab;
|
||||||
size_t usize;
|
size_t usize;
|
||||||
@ -314,8 +314,8 @@ ckh_shrink(tsdn_t *tsdn, ckh_t *ckh)
|
|||||||
usize = sa2u(sizeof(ckhc_t) << lg_curcells, CACHELINE);
|
usize = sa2u(sizeof(ckhc_t) << lg_curcells, CACHELINE);
|
||||||
if (unlikely(usize == 0 || usize > HUGE_MAXCLASS))
|
if (unlikely(usize == 0 || usize > HUGE_MAXCLASS))
|
||||||
return;
|
return;
|
||||||
tab = (ckhc_t *)ipallocztm(tsdn, usize, CACHELINE, true, NULL, true,
|
tab = (ckhc_t *)ipallocztm(tsd_tsdn(tsd), usize, CACHELINE, true, NULL,
|
||||||
arena_ichoose(tsdn, NULL));
|
true, arena_ichoose(tsd, NULL));
|
||||||
if (tab == NULL) {
|
if (tab == NULL) {
|
||||||
/*
|
/*
|
||||||
* An OOM error isn't worth propagating, since it doesn't
|
* An OOM error isn't worth propagating, since it doesn't
|
||||||
@ -330,7 +330,7 @@ ckh_shrink(tsdn_t *tsdn, ckh_t *ckh)
|
|||||||
ckh->lg_curbuckets = lg_curcells - LG_CKH_BUCKET_CELLS;
|
ckh->lg_curbuckets = lg_curcells - LG_CKH_BUCKET_CELLS;
|
||||||
|
|
||||||
if (!ckh_rebuild(ckh, tab)) {
|
if (!ckh_rebuild(ckh, tab)) {
|
||||||
idalloctm(tsdn, tab, NULL, true, true);
|
idalloctm(tsd_tsdn(tsd), tab, NULL, true, true);
|
||||||
#ifdef CKH_COUNT
|
#ifdef CKH_COUNT
|
||||||
ckh->nshrinks++;
|
ckh->nshrinks++;
|
||||||
#endif
|
#endif
|
||||||
@ -338,7 +338,7 @@ ckh_shrink(tsdn_t *tsdn, ckh_t *ckh)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Rebuilding failed, so back out partially rebuilt table. */
|
/* Rebuilding failed, so back out partially rebuilt table. */
|
||||||
idalloctm(tsdn, ckh->tab, NULL, true, true);
|
idalloctm(tsd_tsdn(tsd), ckh->tab, NULL, true, true);
|
||||||
ckh->tab = tab;
|
ckh->tab = tab;
|
||||||
ckh->lg_curbuckets = lg_prevbuckets;
|
ckh->lg_curbuckets = lg_prevbuckets;
|
||||||
#ifdef CKH_COUNT
|
#ifdef CKH_COUNT
|
||||||
@ -347,7 +347,7 @@ ckh_shrink(tsdn_t *tsdn, ckh_t *ckh)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ckh_new(tsdn_t *tsdn, ckh_t *ckh, size_t minitems, ckh_hash_t *hash,
|
ckh_new(tsd_t *tsd, ckh_t *ckh, size_t minitems, ckh_hash_t *hash,
|
||||||
ckh_keycomp_t *keycomp)
|
ckh_keycomp_t *keycomp)
|
||||||
{
|
{
|
||||||
bool ret;
|
bool ret;
|
||||||
@ -391,8 +391,8 @@ ckh_new(tsdn_t *tsdn, ckh_t *ckh, size_t minitems, ckh_hash_t *hash,
|
|||||||
ret = true;
|
ret = true;
|
||||||
goto label_return;
|
goto label_return;
|
||||||
}
|
}
|
||||||
ckh->tab = (ckhc_t *)ipallocztm(tsdn, usize, CACHELINE, true, NULL,
|
ckh->tab = (ckhc_t *)ipallocztm(tsd_tsdn(tsd), usize, CACHELINE, true,
|
||||||
true, arena_ichoose(tsdn, NULL));
|
NULL, true, arena_ichoose(tsd, NULL));
|
||||||
if (ckh->tab == NULL) {
|
if (ckh->tab == NULL) {
|
||||||
ret = true;
|
ret = true;
|
||||||
goto label_return;
|
goto label_return;
|
||||||
@ -404,7 +404,7 @@ label_return:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ckh_delete(tsdn_t *tsdn, ckh_t *ckh)
|
ckh_delete(tsd_t *tsd, ckh_t *ckh)
|
||||||
{
|
{
|
||||||
|
|
||||||
assert(ckh != NULL);
|
assert(ckh != NULL);
|
||||||
@ -421,7 +421,7 @@ ckh_delete(tsdn_t *tsdn, ckh_t *ckh)
|
|||||||
(unsigned long long)ckh->nrelocs);
|
(unsigned long long)ckh->nrelocs);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
idalloctm(tsdn, ckh->tab, NULL, true, true);
|
idalloctm(tsd_tsdn(tsd), ckh->tab, NULL, true, true);
|
||||||
if (config_debug)
|
if (config_debug)
|
||||||
memset(ckh, JEMALLOC_FREE_JUNK, sizeof(ckh_t));
|
memset(ckh, JEMALLOC_FREE_JUNK, sizeof(ckh_t));
|
||||||
}
|
}
|
||||||
@ -456,7 +456,7 @@ ckh_iter(ckh_t *ckh, size_t *tabind, void **key, void **data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ckh_insert(tsdn_t *tsdn, ckh_t *ckh, const void *key, const void *data)
|
ckh_insert(tsd_t *tsd, ckh_t *ckh, const void *key, const void *data)
|
||||||
{
|
{
|
||||||
bool ret;
|
bool ret;
|
||||||
|
|
||||||
@ -468,7 +468,7 @@ ckh_insert(tsdn_t *tsdn, ckh_t *ckh, const void *key, const void *data)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
while (ckh_try_insert(ckh, &key, &data)) {
|
while (ckh_try_insert(ckh, &key, &data)) {
|
||||||
if (ckh_grow(tsdn, ckh)) {
|
if (ckh_grow(tsd, ckh)) {
|
||||||
ret = true;
|
ret = true;
|
||||||
goto label_return;
|
goto label_return;
|
||||||
}
|
}
|
||||||
@ -480,7 +480,7 @@ label_return:
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ckh_remove(tsdn_t *tsdn, ckh_t *ckh, const void *searchkey, void **key,
|
ckh_remove(tsd_t *tsd, ckh_t *ckh, const void *searchkey, void **key,
|
||||||
void **data)
|
void **data)
|
||||||
{
|
{
|
||||||
size_t cell;
|
size_t cell;
|
||||||
@ -502,7 +502,7 @@ ckh_remove(tsdn_t *tsdn, ckh_t *ckh, const void *searchkey, void **key,
|
|||||||
+ LG_CKH_BUCKET_CELLS - 2)) && ckh->lg_curbuckets
|
+ LG_CKH_BUCKET_CELLS - 2)) && ckh->lg_curbuckets
|
||||||
> ckh->lg_minbuckets) {
|
> ckh->lg_minbuckets) {
|
||||||
/* Ignore error due to OOM. */
|
/* Ignore error due to OOM. */
|
||||||
ckh_shrink(tsdn, ckh);
|
ckh_shrink(tsd, ckh);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (false);
|
return (false);
|
||||||
|
@ -1478,7 +1478,7 @@ tcache_create_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
|||||||
|
|
||||||
malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
|
malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
|
||||||
READONLY();
|
READONLY();
|
||||||
if (tcaches_create(tsd_tsdn(tsd), &tcache_ind)) {
|
if (tcaches_create(tsd, &tcache_ind)) {
|
||||||
ret = EFAULT;
|
ret = EFAULT;
|
||||||
goto label_return;
|
goto label_return;
|
||||||
}
|
}
|
||||||
@ -2100,7 +2100,7 @@ prof_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
|||||||
if (lg_sample >= (sizeof(uint64_t) << 3))
|
if (lg_sample >= (sizeof(uint64_t) << 3))
|
||||||
lg_sample = (sizeof(uint64_t) << 3) - 1;
|
lg_sample = (sizeof(uint64_t) << 3) - 1;
|
||||||
|
|
||||||
prof_reset(tsd_tsdn(tsd), lg_sample);
|
prof_reset(tsd, lg_sample);
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
label_return:
|
label_return:
|
||||||
|
@ -54,6 +54,7 @@ huge_palloc(tsdn_t *tsdn, arena_t *arena, size_t usize, size_t alignment,
|
|||||||
{
|
{
|
||||||
void *ret;
|
void *ret;
|
||||||
size_t ausize;
|
size_t ausize;
|
||||||
|
arena_t *iarena;
|
||||||
extent_node_t *node;
|
extent_node_t *node;
|
||||||
bool is_zeroed;
|
bool is_zeroed;
|
||||||
|
|
||||||
@ -67,8 +68,9 @@ huge_palloc(tsdn_t *tsdn, arena_t *arena, size_t usize, size_t alignment,
|
|||||||
assert(ausize >= chunksize);
|
assert(ausize >= chunksize);
|
||||||
|
|
||||||
/* Allocate an extent node with which to track the chunk. */
|
/* Allocate an extent node with which to track the chunk. */
|
||||||
|
iarena = (!tsdn_null(tsdn)) ? arena_ichoose(tsdn_tsd(tsdn), NULL) : a0get();
|
||||||
node = ipallocztm(tsdn, CACHELINE_CEILING(sizeof(extent_node_t)),
|
node = ipallocztm(tsdn, CACHELINE_CEILING(sizeof(extent_node_t)),
|
||||||
CACHELINE, false, NULL, true, arena_ichoose(tsdn, arena));
|
CACHELINE, false, NULL, true, iarena);
|
||||||
if (node == NULL)
|
if (node == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
|
@ -340,6 +340,13 @@ a0idalloc(void *ptr, bool is_metadata)
|
|||||||
idalloctm(TSDN_NULL, ptr, false, is_metadata, true);
|
idalloctm(TSDN_NULL, ptr, false, is_metadata, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
arena_t *
|
||||||
|
a0get(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (a0);
|
||||||
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
a0malloc(size_t size)
|
a0malloc(size_t size)
|
||||||
{
|
{
|
||||||
@ -1454,7 +1461,7 @@ malloc_init_hard(void)
|
|||||||
return (true);
|
return (true);
|
||||||
malloc_mutex_lock(tsd_tsdn(tsd), &init_lock);
|
malloc_mutex_lock(tsd_tsdn(tsd), &init_lock);
|
||||||
|
|
||||||
if (config_prof && prof_boot2(tsd_tsdn(tsd))) {
|
if (config_prof && prof_boot2(tsd)) {
|
||||||
malloc_mutex_unlock(tsd_tsdn(tsd), &init_lock);
|
malloc_mutex_unlock(tsd_tsdn(tsd), &init_lock);
|
||||||
return (true);
|
return (true);
|
||||||
}
|
}
|
||||||
|
85
src/prof.c
85
src/prof.c
@ -125,7 +125,7 @@ static bool prof_tctx_should_destroy(tsdn_t *tsdn, prof_tctx_t *tctx);
|
|||||||
static void prof_tctx_destroy(tsd_t *tsd, prof_tctx_t *tctx);
|
static void prof_tctx_destroy(tsd_t *tsd, prof_tctx_t *tctx);
|
||||||
static bool prof_tdata_should_destroy(tsdn_t *tsdn, prof_tdata_t *tdata,
|
static bool prof_tdata_should_destroy(tsdn_t *tsdn, prof_tdata_t *tdata,
|
||||||
bool even_if_attached);
|
bool even_if_attached);
|
||||||
static void prof_tdata_destroy(tsdn_t *tsdn, prof_tdata_t *tdata,
|
static void prof_tdata_destroy(tsd_t *tsd, prof_tdata_t *tdata,
|
||||||
bool even_if_attached);
|
bool even_if_attached);
|
||||||
static char *prof_thread_name_alloc(tsdn_t *tsdn, const char *thread_name);
|
static char *prof_thread_name_alloc(tsdn_t *tsdn, const char *thread_name);
|
||||||
|
|
||||||
@ -591,7 +591,7 @@ prof_gctx_try_destroy(tsd_t *tsd, prof_tdata_t *tdata_self, prof_gctx_t *gctx,
|
|||||||
assert(gctx->nlimbo != 0);
|
assert(gctx->nlimbo != 0);
|
||||||
if (tctx_tree_empty(&gctx->tctxs) && gctx->nlimbo == 1) {
|
if (tctx_tree_empty(&gctx->tctxs) && gctx->nlimbo == 1) {
|
||||||
/* Remove gctx from bt2gctx. */
|
/* Remove gctx from bt2gctx. */
|
||||||
if (ckh_remove(tsd_tsdn(tsd), &bt2gctx, &gctx->bt, NULL, NULL))
|
if (ckh_remove(tsd, &bt2gctx, &gctx->bt, NULL, NULL))
|
||||||
not_reached();
|
not_reached();
|
||||||
prof_leave(tsd, tdata_self);
|
prof_leave(tsd, tdata_self);
|
||||||
/* Destroy gctx. */
|
/* Destroy gctx. */
|
||||||
@ -651,7 +651,7 @@ prof_tctx_destroy(tsd_t *tsd, prof_tctx_t *tctx)
|
|||||||
assert(tctx->cnts.accumobjs == 0);
|
assert(tctx->cnts.accumobjs == 0);
|
||||||
assert(tctx->cnts.accumbytes == 0);
|
assert(tctx->cnts.accumbytes == 0);
|
||||||
|
|
||||||
ckh_remove(tsd_tsdn(tsd), &tdata->bt2tctx, &gctx->bt, NULL, NULL);
|
ckh_remove(tsd, &tdata->bt2tctx, &gctx->bt, NULL, NULL);
|
||||||
destroy_tdata = prof_tdata_should_destroy(tsd_tsdn(tsd), tdata, false);
|
destroy_tdata = prof_tdata_should_destroy(tsd_tsdn(tsd), tdata, false);
|
||||||
malloc_mutex_unlock(tsd_tsdn(tsd), tdata->lock);
|
malloc_mutex_unlock(tsd_tsdn(tsd), tdata->lock);
|
||||||
|
|
||||||
@ -704,7 +704,7 @@ prof_tctx_destroy(tsd_t *tsd, prof_tctx_t *tctx)
|
|||||||
malloc_mutex_assert_not_owner(tsd_tsdn(tsd), tctx->tdata->lock);
|
malloc_mutex_assert_not_owner(tsd_tsdn(tsd), tctx->tdata->lock);
|
||||||
|
|
||||||
if (destroy_tdata)
|
if (destroy_tdata)
|
||||||
prof_tdata_destroy(tsd_tsdn(tsd), tdata, false);
|
prof_tdata_destroy(tsd, tdata, false);
|
||||||
|
|
||||||
if (destroy_tctx)
|
if (destroy_tctx)
|
||||||
idalloctm(tsd_tsdn(tsd), tctx, NULL, true, true);
|
idalloctm(tsd_tsdn(tsd), tctx, NULL, true, true);
|
||||||
@ -733,7 +733,7 @@ prof_lookup_global(tsd_t *tsd, prof_bt_t *bt, prof_tdata_t *tdata,
|
|||||||
return (true);
|
return (true);
|
||||||
}
|
}
|
||||||
btkey.p = &gctx.p->bt;
|
btkey.p = &gctx.p->bt;
|
||||||
if (ckh_insert(tsd_tsdn(tsd), &bt2gctx, btkey.v, gctx.v)) {
|
if (ckh_insert(tsd, &bt2gctx, btkey.v, gctx.v)) {
|
||||||
/* OOM. */
|
/* OOM. */
|
||||||
prof_leave(tsd, tdata);
|
prof_leave(tsd, tdata);
|
||||||
idalloctm(tsd_tsdn(tsd), gctx.v, NULL, true, true);
|
idalloctm(tsd_tsdn(tsd), gctx.v, NULL, true, true);
|
||||||
@ -795,7 +795,7 @@ prof_lookup(tsd_t *tsd, prof_bt_t *bt)
|
|||||||
/* Link a prof_tctx_t into gctx for this thread. */
|
/* Link a prof_tctx_t into gctx for this thread. */
|
||||||
ret.v = iallocztm(tsd_tsdn(tsd), sizeof(prof_tctx_t),
|
ret.v = iallocztm(tsd_tsdn(tsd), sizeof(prof_tctx_t),
|
||||||
size2index(sizeof(prof_tctx_t)), false, NULL, true,
|
size2index(sizeof(prof_tctx_t)), false, NULL, true,
|
||||||
arena_ichoose(tsd_tsdn(tsd), NULL), true);
|
arena_ichoose(tsd, NULL), true);
|
||||||
if (ret.p == NULL) {
|
if (ret.p == NULL) {
|
||||||
if (new_gctx)
|
if (new_gctx)
|
||||||
prof_gctx_try_destroy(tsd, tdata, gctx, tdata);
|
prof_gctx_try_destroy(tsd, tdata, gctx, tdata);
|
||||||
@ -810,8 +810,7 @@ prof_lookup(tsd_t *tsd, prof_bt_t *bt)
|
|||||||
ret.p->prepared = true;
|
ret.p->prepared = true;
|
||||||
ret.p->state = prof_tctx_state_initializing;
|
ret.p->state = prof_tctx_state_initializing;
|
||||||
malloc_mutex_lock(tsd_tsdn(tsd), tdata->lock);
|
malloc_mutex_lock(tsd_tsdn(tsd), tdata->lock);
|
||||||
error = ckh_insert(tsd_tsdn(tsd), &tdata->bt2tctx, btkey,
|
error = ckh_insert(tsd, &tdata->bt2tctx, btkey, ret.v);
|
||||||
ret.v);
|
|
||||||
malloc_mutex_unlock(tsd_tsdn(tsd), tdata->lock);
|
malloc_mutex_unlock(tsd_tsdn(tsd), tdata->lock);
|
||||||
if (error) {
|
if (error) {
|
||||||
if (new_gctx)
|
if (new_gctx)
|
||||||
@ -1791,7 +1790,7 @@ prof_thr_uid_alloc(tsdn_t *tsdn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static prof_tdata_t *
|
static prof_tdata_t *
|
||||||
prof_tdata_init_impl(tsdn_t *tsdn, uint64_t thr_uid, uint64_t thr_discrim,
|
prof_tdata_init_impl(tsd_t *tsd, uint64_t thr_uid, uint64_t thr_discrim,
|
||||||
char *thread_name, bool active)
|
char *thread_name, bool active)
|
||||||
{
|
{
|
||||||
prof_tdata_t *tdata;
|
prof_tdata_t *tdata;
|
||||||
@ -1799,7 +1798,7 @@ prof_tdata_init_impl(tsdn_t *tsdn, uint64_t thr_uid, uint64_t thr_discrim,
|
|||||||
cassert(config_prof);
|
cassert(config_prof);
|
||||||
|
|
||||||
/* Initialize an empty cache for this thread. */
|
/* Initialize an empty cache for this thread. */
|
||||||
tdata = (prof_tdata_t *)iallocztm(tsdn, sizeof(prof_tdata_t),
|
tdata = (prof_tdata_t *)iallocztm(tsd_tsdn(tsd), sizeof(prof_tdata_t),
|
||||||
size2index(sizeof(prof_tdata_t)), false, NULL, true,
|
size2index(sizeof(prof_tdata_t)), false, NULL, true,
|
||||||
arena_get(TSDN_NULL, 0, true), true);
|
arena_get(TSDN_NULL, 0, true), true);
|
||||||
if (tdata == NULL)
|
if (tdata == NULL)
|
||||||
@ -1813,9 +1812,9 @@ prof_tdata_init_impl(tsdn_t *tsdn, uint64_t thr_uid, uint64_t thr_discrim,
|
|||||||
tdata->expired = false;
|
tdata->expired = false;
|
||||||
tdata->tctx_uid_next = 0;
|
tdata->tctx_uid_next = 0;
|
||||||
|
|
||||||
if (ckh_new(tsdn, &tdata->bt2tctx, PROF_CKH_MINITEMS,
|
if (ckh_new(tsd, &tdata->bt2tctx, PROF_CKH_MINITEMS, prof_bt_hash,
|
||||||
prof_bt_hash, prof_bt_keycomp)) {
|
prof_bt_keycomp)) {
|
||||||
idalloctm(tsdn, tdata, NULL, true, true);
|
idalloctm(tsd_tsdn(tsd), tdata, NULL, true, true);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1829,19 +1828,19 @@ prof_tdata_init_impl(tsdn_t *tsdn, uint64_t thr_uid, uint64_t thr_discrim,
|
|||||||
tdata->dumping = false;
|
tdata->dumping = false;
|
||||||
tdata->active = active;
|
tdata->active = active;
|
||||||
|
|
||||||
malloc_mutex_lock(tsdn, &tdatas_mtx);
|
malloc_mutex_lock(tsd_tsdn(tsd), &tdatas_mtx);
|
||||||
tdata_tree_insert(&tdatas, tdata);
|
tdata_tree_insert(&tdatas, tdata);
|
||||||
malloc_mutex_unlock(tsdn, &tdatas_mtx);
|
malloc_mutex_unlock(tsd_tsdn(tsd), &tdatas_mtx);
|
||||||
|
|
||||||
return (tdata);
|
return (tdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
prof_tdata_t *
|
prof_tdata_t *
|
||||||
prof_tdata_init(tsdn_t *tsdn)
|
prof_tdata_init(tsd_t *tsd)
|
||||||
{
|
{
|
||||||
|
|
||||||
return (prof_tdata_init_impl(tsdn, prof_thr_uid_alloc(tsdn), 0, NULL,
|
return (prof_tdata_init_impl(tsd, prof_thr_uid_alloc(tsd_tsdn(tsd)), 0,
|
||||||
prof_thread_active_init_get(tsdn)));
|
NULL, prof_thread_active_init_get(tsd_tsdn(tsd))));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
@ -1866,31 +1865,29 @@ prof_tdata_should_destroy(tsdn_t *tsdn, prof_tdata_t *tdata,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
prof_tdata_destroy_locked(tsdn_t *tsdn, prof_tdata_t *tdata,
|
prof_tdata_destroy_locked(tsd_t *tsd, prof_tdata_t *tdata,
|
||||||
bool even_if_attached)
|
bool even_if_attached)
|
||||||
{
|
{
|
||||||
|
|
||||||
malloc_mutex_assert_owner(tsdn, &tdatas_mtx);
|
malloc_mutex_assert_owner(tsd_tsdn(tsd), &tdatas_mtx);
|
||||||
|
|
||||||
assert(tsdn_null(tsdn) || tsd_prof_tdata_get(tsdn_tsd(tsdn)) != tdata);
|
|
||||||
|
|
||||||
tdata_tree_remove(&tdatas, tdata);
|
tdata_tree_remove(&tdatas, tdata);
|
||||||
|
|
||||||
assert(prof_tdata_should_destroy_unlocked(tdata, even_if_attached));
|
assert(prof_tdata_should_destroy_unlocked(tdata, even_if_attached));
|
||||||
|
|
||||||
if (tdata->thread_name != NULL)
|
if (tdata->thread_name != NULL)
|
||||||
idalloctm(tsdn, tdata->thread_name, NULL, true, true);
|
idalloctm(tsd_tsdn(tsd), tdata->thread_name, NULL, true, true);
|
||||||
ckh_delete(tsdn, &tdata->bt2tctx);
|
ckh_delete(tsd, &tdata->bt2tctx);
|
||||||
idalloctm(tsdn, tdata, NULL, true, true);
|
idalloctm(tsd_tsdn(tsd), tdata, NULL, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
prof_tdata_destroy(tsdn_t *tsdn, prof_tdata_t *tdata, bool even_if_attached)
|
prof_tdata_destroy(tsd_t *tsd, prof_tdata_t *tdata, bool even_if_attached)
|
||||||
{
|
{
|
||||||
|
|
||||||
malloc_mutex_lock(tsdn, &tdatas_mtx);
|
malloc_mutex_lock(tsd_tsdn(tsd), &tdatas_mtx);
|
||||||
prof_tdata_destroy_locked(tsdn, tdata, even_if_attached);
|
prof_tdata_destroy_locked(tsd, tdata, even_if_attached);
|
||||||
malloc_mutex_unlock(tsdn, &tdatas_mtx);
|
malloc_mutex_unlock(tsd_tsdn(tsd), &tdatas_mtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1913,7 +1910,7 @@ prof_tdata_detach(tsd_t *tsd, prof_tdata_t *tdata)
|
|||||||
destroy_tdata = false;
|
destroy_tdata = false;
|
||||||
malloc_mutex_unlock(tsd_tsdn(tsd), tdata->lock);
|
malloc_mutex_unlock(tsd_tsdn(tsd), tdata->lock);
|
||||||
if (destroy_tdata)
|
if (destroy_tdata)
|
||||||
prof_tdata_destroy(tsd_tsdn(tsd), tdata, true);
|
prof_tdata_destroy(tsd, tdata, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
prof_tdata_t *
|
prof_tdata_t *
|
||||||
@ -1926,8 +1923,8 @@ prof_tdata_reinit(tsd_t *tsd, prof_tdata_t *tdata)
|
|||||||
bool active = tdata->active;
|
bool active = tdata->active;
|
||||||
|
|
||||||
prof_tdata_detach(tsd, tdata);
|
prof_tdata_detach(tsd, tdata);
|
||||||
return (prof_tdata_init_impl(tsd_tsdn(tsd), thr_uid, thr_discrim,
|
return (prof_tdata_init_impl(tsd, thr_uid, thr_discrim, thread_name,
|
||||||
thread_name, active));
|
active));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
@ -1956,30 +1953,30 @@ prof_tdata_reset_iter(prof_tdata_tree_t *tdatas, prof_tdata_t *tdata, void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
prof_reset(tsdn_t *tsdn, size_t lg_sample)
|
prof_reset(tsd_t *tsd, size_t lg_sample)
|
||||||
{
|
{
|
||||||
prof_tdata_t *next;
|
prof_tdata_t *next;
|
||||||
|
|
||||||
assert(lg_sample < (sizeof(uint64_t) << 3));
|
assert(lg_sample < (sizeof(uint64_t) << 3));
|
||||||
|
|
||||||
malloc_mutex_lock(tsdn, &prof_dump_mtx);
|
malloc_mutex_lock(tsd_tsdn(tsd), &prof_dump_mtx);
|
||||||
malloc_mutex_lock(tsdn, &tdatas_mtx);
|
malloc_mutex_lock(tsd_tsdn(tsd), &tdatas_mtx);
|
||||||
|
|
||||||
lg_prof_sample = lg_sample;
|
lg_prof_sample = lg_sample;
|
||||||
|
|
||||||
next = NULL;
|
next = NULL;
|
||||||
do {
|
do {
|
||||||
prof_tdata_t *to_destroy = tdata_tree_iter(&tdatas, next,
|
prof_tdata_t *to_destroy = tdata_tree_iter(&tdatas, next,
|
||||||
prof_tdata_reset_iter, (void *)tsdn);
|
prof_tdata_reset_iter, (void *)tsd);
|
||||||
if (to_destroy != NULL) {
|
if (to_destroy != NULL) {
|
||||||
next = tdata_tree_next(&tdatas, to_destroy);
|
next = tdata_tree_next(&tdatas, to_destroy);
|
||||||
prof_tdata_destroy_locked(tsdn, to_destroy, false);
|
prof_tdata_destroy_locked(tsd, to_destroy, false);
|
||||||
} else
|
} else
|
||||||
next = NULL;
|
next = NULL;
|
||||||
} while (next != NULL);
|
} while (next != NULL);
|
||||||
|
|
||||||
malloc_mutex_unlock(tsdn, &tdatas_mtx);
|
malloc_mutex_unlock(tsd_tsdn(tsd), &tdatas_mtx);
|
||||||
malloc_mutex_unlock(tsdn, &prof_dump_mtx);
|
malloc_mutex_unlock(tsd_tsdn(tsd), &prof_dump_mtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -2189,7 +2186,7 @@ prof_boot1(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
prof_boot2(tsdn_t *tsdn)
|
prof_boot2(tsd_t *tsd)
|
||||||
{
|
{
|
||||||
|
|
||||||
cassert(config_prof);
|
cassert(config_prof);
|
||||||
@ -2215,7 +2212,7 @@ prof_boot2(tsdn_t *tsdn)
|
|||||||
WITNESS_RANK_PROF_THREAD_ACTIVE_INIT))
|
WITNESS_RANK_PROF_THREAD_ACTIVE_INIT))
|
||||||
return (true);
|
return (true);
|
||||||
|
|
||||||
if (ckh_new(tsdn, &bt2gctx, PROF_CKH_MINITEMS, prof_bt_hash,
|
if (ckh_new(tsd, &bt2gctx, PROF_CKH_MINITEMS, prof_bt_hash,
|
||||||
prof_bt_keycomp))
|
prof_bt_keycomp))
|
||||||
return (true);
|
return (true);
|
||||||
if (malloc_mutex_init(&bt2gctx_mtx, "prof_bt2gctx",
|
if (malloc_mutex_init(&bt2gctx_mtx, "prof_bt2gctx",
|
||||||
@ -2246,8 +2243,8 @@ prof_boot2(tsdn_t *tsdn)
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
gctx_locks = (malloc_mutex_t *)base_alloc(tsdn, PROF_NCTX_LOCKS
|
gctx_locks = (malloc_mutex_t *)base_alloc(tsd_tsdn(tsd),
|
||||||
* sizeof(malloc_mutex_t));
|
PROF_NCTX_LOCKS * sizeof(malloc_mutex_t));
|
||||||
if (gctx_locks == NULL)
|
if (gctx_locks == NULL)
|
||||||
return (true);
|
return (true);
|
||||||
for (i = 0; i < PROF_NCTX_LOCKS; i++) {
|
for (i = 0; i < PROF_NCTX_LOCKS; i++) {
|
||||||
@ -2256,7 +2253,7 @@ prof_boot2(tsdn_t *tsdn)
|
|||||||
return (true);
|
return (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
tdata_locks = (malloc_mutex_t *)base_alloc(tsdn,
|
tdata_locks = (malloc_mutex_t *)base_alloc(tsd_tsdn(tsd),
|
||||||
PROF_NTDATA_LOCKS * sizeof(malloc_mutex_t));
|
PROF_NTDATA_LOCKS * sizeof(malloc_mutex_t));
|
||||||
if (tdata_locks == NULL)
|
if (tdata_locks == NULL)
|
||||||
return (true);
|
return (true);
|
||||||
|
@ -445,14 +445,14 @@ tcache_stats_merge(tsdn_t *tsdn, tcache_t *tcache, arena_t *arena)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
tcaches_create(tsdn_t *tsdn, unsigned *r_ind)
|
tcaches_create(tsd_t *tsd, unsigned *r_ind)
|
||||||
{
|
{
|
||||||
arena_t *arena;
|
arena_t *arena;
|
||||||
tcache_t *tcache;
|
tcache_t *tcache;
|
||||||
tcaches_t *elm;
|
tcaches_t *elm;
|
||||||
|
|
||||||
if (tcaches == NULL) {
|
if (tcaches == NULL) {
|
||||||
tcaches = base_alloc(tsdn, sizeof(tcache_t *) *
|
tcaches = base_alloc(tsd_tsdn(tsd), sizeof(tcache_t *) *
|
||||||
(MALLOCX_TCACHE_MAX+1));
|
(MALLOCX_TCACHE_MAX+1));
|
||||||
if (tcaches == NULL)
|
if (tcaches == NULL)
|
||||||
return (true);
|
return (true);
|
||||||
@ -460,10 +460,10 @@ tcaches_create(tsdn_t *tsdn, unsigned *r_ind)
|
|||||||
|
|
||||||
if (tcaches_avail == NULL && tcaches_past > MALLOCX_TCACHE_MAX)
|
if (tcaches_avail == NULL && tcaches_past > MALLOCX_TCACHE_MAX)
|
||||||
return (true);
|
return (true);
|
||||||
arena = arena_ichoose(tsdn, NULL);
|
arena = arena_ichoose(tsd, NULL);
|
||||||
if (unlikely(arena == NULL))
|
if (unlikely(arena == NULL))
|
||||||
return (true);
|
return (true);
|
||||||
tcache = tcache_create(tsdn, arena);
|
tcache = tcache_create(tsd_tsdn(tsd), arena);
|
||||||
if (tcache == NULL)
|
if (tcache == NULL)
|
||||||
return (true);
|
return (true);
|
||||||
|
|
||||||
|
@ -2,24 +2,24 @@
|
|||||||
|
|
||||||
TEST_BEGIN(test_new_delete)
|
TEST_BEGIN(test_new_delete)
|
||||||
{
|
{
|
||||||
tsdn_t *tsdn;
|
tsd_t *tsd;
|
||||||
ckh_t ckh;
|
ckh_t ckh;
|
||||||
|
|
||||||
tsdn = tsdn_fetch();
|
tsd = tsd_fetch();
|
||||||
|
|
||||||
assert_false(ckh_new(tsdn, &ckh, 2, ckh_string_hash,
|
assert_false(ckh_new(tsd, &ckh, 2, ckh_string_hash,
|
||||||
ckh_string_keycomp), "Unexpected ckh_new() error");
|
ckh_string_keycomp), "Unexpected ckh_new() error");
|
||||||
ckh_delete(tsdn, &ckh);
|
ckh_delete(tsd, &ckh);
|
||||||
|
|
||||||
assert_false(ckh_new(tsdn, &ckh, 3, ckh_pointer_hash,
|
assert_false(ckh_new(tsd, &ckh, 3, ckh_pointer_hash,
|
||||||
ckh_pointer_keycomp), "Unexpected ckh_new() error");
|
ckh_pointer_keycomp), "Unexpected ckh_new() error");
|
||||||
ckh_delete(tsdn, &ckh);
|
ckh_delete(tsd, &ckh);
|
||||||
}
|
}
|
||||||
TEST_END
|
TEST_END
|
||||||
|
|
||||||
TEST_BEGIN(test_count_insert_search_remove)
|
TEST_BEGIN(test_count_insert_search_remove)
|
||||||
{
|
{
|
||||||
tsdn_t *tsdn;
|
tsd_t *tsd;
|
||||||
ckh_t ckh;
|
ckh_t ckh;
|
||||||
const char *strs[] = {
|
const char *strs[] = {
|
||||||
"a string",
|
"a string",
|
||||||
@ -30,9 +30,9 @@ TEST_BEGIN(test_count_insert_search_remove)
|
|||||||
const char *missing = "A string not in the hash table.";
|
const char *missing = "A string not in the hash table.";
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
tsdn = tsdn_fetch();
|
tsd = tsd_fetch();
|
||||||
|
|
||||||
assert_false(ckh_new(tsdn, &ckh, 2, ckh_string_hash,
|
assert_false(ckh_new(tsd, &ckh, 2, ckh_string_hash,
|
||||||
ckh_string_keycomp), "Unexpected ckh_new() error");
|
ckh_string_keycomp), "Unexpected ckh_new() error");
|
||||||
assert_zu_eq(ckh_count(&ckh), 0,
|
assert_zu_eq(ckh_count(&ckh), 0,
|
||||||
"ckh_count() should return %zu, but it returned %zu", ZU(0),
|
"ckh_count() should return %zu, but it returned %zu", ZU(0),
|
||||||
@ -40,7 +40,7 @@ TEST_BEGIN(test_count_insert_search_remove)
|
|||||||
|
|
||||||
/* Insert. */
|
/* Insert. */
|
||||||
for (i = 0; i < sizeof(strs)/sizeof(const char *); i++) {
|
for (i = 0; i < sizeof(strs)/sizeof(const char *); i++) {
|
||||||
ckh_insert(tsdn, &ckh, strs[i], strs[i]);
|
ckh_insert(tsd, &ckh, strs[i], strs[i]);
|
||||||
assert_zu_eq(ckh_count(&ckh), i+1,
|
assert_zu_eq(ckh_count(&ckh), i+1,
|
||||||
"ckh_count() should return %zu, but it returned %zu", i+1,
|
"ckh_count() should return %zu, but it returned %zu", i+1,
|
||||||
ckh_count(&ckh));
|
ckh_count(&ckh));
|
||||||
@ -85,7 +85,7 @@ TEST_BEGIN(test_count_insert_search_remove)
|
|||||||
vp = (i & 2) ? &v.p : NULL;
|
vp = (i & 2) ? &v.p : NULL;
|
||||||
k.p = NULL;
|
k.p = NULL;
|
||||||
v.p = NULL;
|
v.p = NULL;
|
||||||
assert_false(ckh_remove(tsdn, &ckh, strs[i], kp, vp),
|
assert_false(ckh_remove(tsd, &ckh, strs[i], kp, vp),
|
||||||
"Unexpected ckh_remove() error");
|
"Unexpected ckh_remove() error");
|
||||||
|
|
||||||
ks = (i & 1) ? strs[i] : (const char *)NULL;
|
ks = (i & 1) ? strs[i] : (const char *)NULL;
|
||||||
@ -101,22 +101,22 @@ TEST_BEGIN(test_count_insert_search_remove)
|
|||||||
ckh_count(&ckh));
|
ckh_count(&ckh));
|
||||||
}
|
}
|
||||||
|
|
||||||
ckh_delete(tsdn, &ckh);
|
ckh_delete(tsd, &ckh);
|
||||||
}
|
}
|
||||||
TEST_END
|
TEST_END
|
||||||
|
|
||||||
TEST_BEGIN(test_insert_iter_remove)
|
TEST_BEGIN(test_insert_iter_remove)
|
||||||
{
|
{
|
||||||
#define NITEMS ZU(1000)
|
#define NITEMS ZU(1000)
|
||||||
tsdn_t *tsdn;
|
tsd_t *tsd;
|
||||||
ckh_t ckh;
|
ckh_t ckh;
|
||||||
void **p[NITEMS];
|
void **p[NITEMS];
|
||||||
void *q, *r;
|
void *q, *r;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
tsdn = tsdn_fetch();
|
tsd = tsd_fetch();
|
||||||
|
|
||||||
assert_false(ckh_new(tsdn, &ckh, 2, ckh_pointer_hash,
|
assert_false(ckh_new(tsd, &ckh, 2, ckh_pointer_hash,
|
||||||
ckh_pointer_keycomp), "Unexpected ckh_new() error");
|
ckh_pointer_keycomp), "Unexpected ckh_new() error");
|
||||||
|
|
||||||
for (i = 0; i < NITEMS; i++) {
|
for (i = 0; i < NITEMS; i++) {
|
||||||
@ -128,7 +128,7 @@ TEST_BEGIN(test_insert_iter_remove)
|
|||||||
size_t j;
|
size_t j;
|
||||||
|
|
||||||
for (j = i; j < NITEMS; j++) {
|
for (j = i; j < NITEMS; j++) {
|
||||||
assert_false(ckh_insert(tsdn, &ckh, p[j], p[j]),
|
assert_false(ckh_insert(tsd, &ckh, p[j], p[j]),
|
||||||
"Unexpected ckh_insert() failure");
|
"Unexpected ckh_insert() failure");
|
||||||
assert_false(ckh_search(&ckh, p[j], &q, &r),
|
assert_false(ckh_search(&ckh, p[j], &q, &r),
|
||||||
"Unexpected ckh_search() failure");
|
"Unexpected ckh_search() failure");
|
||||||
@ -143,13 +143,13 @@ TEST_BEGIN(test_insert_iter_remove)
|
|||||||
for (j = i + 1; j < NITEMS; j++) {
|
for (j = i + 1; j < NITEMS; j++) {
|
||||||
assert_false(ckh_search(&ckh, p[j], NULL, NULL),
|
assert_false(ckh_search(&ckh, p[j], NULL, NULL),
|
||||||
"Unexpected ckh_search() failure");
|
"Unexpected ckh_search() failure");
|
||||||
assert_false(ckh_remove(tsdn, &ckh, p[j], &q, &r),
|
assert_false(ckh_remove(tsd, &ckh, p[j], &q, &r),
|
||||||
"Unexpected ckh_remove() failure");
|
"Unexpected ckh_remove() failure");
|
||||||
assert_ptr_eq(p[j], q, "Key pointer mismatch");
|
assert_ptr_eq(p[j], q, "Key pointer mismatch");
|
||||||
assert_ptr_eq(p[j], r, "Value pointer mismatch");
|
assert_ptr_eq(p[j], r, "Value pointer mismatch");
|
||||||
assert_true(ckh_search(&ckh, p[j], NULL, NULL),
|
assert_true(ckh_search(&ckh, p[j], NULL, NULL),
|
||||||
"Unexpected ckh_search() success");
|
"Unexpected ckh_search() success");
|
||||||
assert_true(ckh_remove(tsdn, &ckh, p[j], &q, &r),
|
assert_true(ckh_remove(tsd, &ckh, p[j], &q, &r),
|
||||||
"Unexpected ckh_remove() success");
|
"Unexpected ckh_remove() success");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,13 +184,13 @@ TEST_BEGIN(test_insert_iter_remove)
|
|||||||
for (i = 0; i < NITEMS; i++) {
|
for (i = 0; i < NITEMS; i++) {
|
||||||
assert_false(ckh_search(&ckh, p[i], NULL, NULL),
|
assert_false(ckh_search(&ckh, p[i], NULL, NULL),
|
||||||
"Unexpected ckh_search() failure");
|
"Unexpected ckh_search() failure");
|
||||||
assert_false(ckh_remove(tsdn, &ckh, p[i], &q, &r),
|
assert_false(ckh_remove(tsd, &ckh, p[i], &q, &r),
|
||||||
"Unexpected ckh_remove() failure");
|
"Unexpected ckh_remove() failure");
|
||||||
assert_ptr_eq(p[i], q, "Key pointer mismatch");
|
assert_ptr_eq(p[i], q, "Key pointer mismatch");
|
||||||
assert_ptr_eq(p[i], r, "Value pointer mismatch");
|
assert_ptr_eq(p[i], r, "Value pointer mismatch");
|
||||||
assert_true(ckh_search(&ckh, p[i], NULL, NULL),
|
assert_true(ckh_search(&ckh, p[i], NULL, NULL),
|
||||||
"Unexpected ckh_search() success");
|
"Unexpected ckh_search() success");
|
||||||
assert_true(ckh_remove(tsdn, &ckh, p[i], &q, &r),
|
assert_true(ckh_remove(tsd, &ckh, p[i], &q, &r),
|
||||||
"Unexpected ckh_remove() success");
|
"Unexpected ckh_remove() success");
|
||||||
dallocx(p[i], 0);
|
dallocx(p[i], 0);
|
||||||
}
|
}
|
||||||
@ -198,7 +198,7 @@ TEST_BEGIN(test_insert_iter_remove)
|
|||||||
assert_zu_eq(ckh_count(&ckh), 0,
|
assert_zu_eq(ckh_count(&ckh), 0,
|
||||||
"ckh_count() should return %zu, but it returned %zu",
|
"ckh_count() should return %zu, but it returned %zu",
|
||||||
ZU(0), ckh_count(&ckh));
|
ZU(0), ckh_count(&ckh));
|
||||||
ckh_delete(tsdn, &ckh);
|
ckh_delete(tsd, &ckh);
|
||||||
#undef NITEMS
|
#undef NITEMS
|
||||||
}
|
}
|
||||||
TEST_END
|
TEST_END
|
||||||
|
@ -58,18 +58,18 @@ thd_start(void *arg)
|
|||||||
data_t d = (data_t)(uintptr_t)arg;
|
data_t d = (data_t)(uintptr_t)arg;
|
||||||
void *p;
|
void *p;
|
||||||
|
|
||||||
assert_x_eq(*data_tsd_get(), DATA_INIT,
|
assert_x_eq(*data_tsd_get(true), DATA_INIT,
|
||||||
"Initial tsd get should return initialization value");
|
"Initial tsd get should return initialization value");
|
||||||
|
|
||||||
p = malloc(1);
|
p = malloc(1);
|
||||||
assert_ptr_not_null(p, "Unexpected malloc() failure");
|
assert_ptr_not_null(p, "Unexpected malloc() failure");
|
||||||
|
|
||||||
data_tsd_set(&d);
|
data_tsd_set(&d);
|
||||||
assert_x_eq(*data_tsd_get(), d,
|
assert_x_eq(*data_tsd_get(true), d,
|
||||||
"After tsd set, tsd get should return value that was set");
|
"After tsd set, tsd get should return value that was set");
|
||||||
|
|
||||||
d = 0;
|
d = 0;
|
||||||
assert_x_eq(*data_tsd_get(), (data_t)(uintptr_t)arg,
|
assert_x_eq(*data_tsd_get(true), (data_t)(uintptr_t)arg,
|
||||||
"Resetting local data should have no effect on tsd");
|
"Resetting local data should have no effect on tsd");
|
||||||
|
|
||||||
free(p);
|
free(p);
|
||||||
|
Loading…
Reference in New Issue
Block a user