Move file handling logic in prof to prof_sys
This commit is contained in:
parent
03ae509f32
commit
767a2e1790
@ -58,11 +58,9 @@ void prof_malloc_sample_object(tsd_t *tsd, const void *ptr, size_t size,
|
|||||||
void prof_free_sampled_object(tsd_t *tsd, size_t usize, prof_info_t *prof_info);
|
void prof_free_sampled_object(tsd_t *tsd, size_t usize, prof_info_t *prof_info);
|
||||||
prof_tctx_t *prof_tctx_create(tsd_t *tsd);
|
prof_tctx_t *prof_tctx_create(tsd_t *tsd);
|
||||||
int prof_getpid(void);
|
int prof_getpid(void);
|
||||||
void prof_get_default_filename(tsdn_t *tsdn, char *filename, uint64_t ind);
|
|
||||||
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);
|
||||||
bool prof_dump_prefix_set(tsdn_t *tsdn, const char *prefix);
|
|
||||||
|
|
||||||
void prof_reset(tsd_t *tsd, 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);
|
||||||
|
@ -1,10 +1,20 @@
|
|||||||
#ifndef JEMALLOC_INTERNAL_PROF_SYS_H
|
#ifndef JEMALLOC_INTERNAL_PROF_SYS_H
|
||||||
#define JEMALLOC_INTERNAL_PROF_SYS_H
|
#define JEMALLOC_INTERNAL_PROF_SYS_H
|
||||||
|
|
||||||
|
extern malloc_mutex_t prof_dump_filename_mtx;
|
||||||
|
extern base_t *prof_base;
|
||||||
|
|
||||||
void prof_sys_thread_name_fetch(tsd_t *tsd);
|
void prof_sys_thread_name_fetch(tsd_t *tsd);
|
||||||
|
|
||||||
/* Used in unit tests. */
|
/* Used in unit tests. */
|
||||||
typedef int (prof_sys_thread_name_read_t)(char *buf, size_t limit);
|
typedef int (prof_sys_thread_name_read_t)(char *buf, size_t limit);
|
||||||
extern prof_sys_thread_name_read_t *JET_MUTABLE prof_sys_thread_name_read;
|
extern prof_sys_thread_name_read_t *JET_MUTABLE prof_sys_thread_name_read;
|
||||||
|
|
||||||
|
void prof_get_default_filename(tsdn_t *tsdn, char *filename, uint64_t ind);
|
||||||
|
bool prof_dump_prefix_set(tsdn_t *tsdn, const char *prefix);
|
||||||
|
void prof_fdump_impl(tsd_t *tsd);
|
||||||
|
void prof_idump_impl(tsd_t *tsd);
|
||||||
|
bool prof_mdump_impl(tsd_t *tsd, const char *filename);
|
||||||
|
void prof_gdump_impl(tsd_t *tsd);
|
||||||
|
|
||||||
#endif /* JEMALLOC_INTERNAL_PROF_SYS_H */
|
#endif /* JEMALLOC_INTERNAL_PROF_SYS_H */
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "jemalloc/internal/mutex.h"
|
#include "jemalloc/internal/mutex.h"
|
||||||
#include "jemalloc/internal/nstime.h"
|
#include "jemalloc/internal/nstime.h"
|
||||||
#include "jemalloc/internal/peak_event.h"
|
#include "jemalloc/internal/peak_event.h"
|
||||||
|
#include "jemalloc/internal/prof_sys.h"
|
||||||
#include "jemalloc/internal/sc.h"
|
#include "jemalloc/internal/sc.h"
|
||||||
#include "jemalloc/internal/util.h"
|
#include "jemalloc/internal/util.h"
|
||||||
|
|
||||||
|
142
src/prof.c
142
src/prof.c
@ -86,38 +86,13 @@ malloc_mutex_t tdatas_mtx;
|
|||||||
static uint64_t next_thr_uid;
|
static uint64_t next_thr_uid;
|
||||||
static malloc_mutex_t next_thr_uid_mtx;
|
static malloc_mutex_t next_thr_uid_mtx;
|
||||||
|
|
||||||
static malloc_mutex_t prof_dump_filename_mtx;
|
|
||||||
static uint64_t prof_dump_seq;
|
|
||||||
static uint64_t prof_dump_iseq;
|
|
||||||
static uint64_t prof_dump_mseq;
|
|
||||||
static uint64_t prof_dump_useq;
|
|
||||||
|
|
||||||
/* The fallback allocator profiling functionality will use. */
|
|
||||||
base_t *prof_base;
|
|
||||||
|
|
||||||
malloc_mutex_t prof_dump_mtx;
|
malloc_mutex_t prof_dump_mtx;
|
||||||
static char *prof_dump_prefix = NULL;
|
|
||||||
|
|
||||||
/* Do not dump any profiles until bootstrapping is complete. */
|
/* Do not dump any profiles until bootstrapping is complete. */
|
||||||
bool prof_booted = false;
|
bool prof_booted = false;
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
/*
|
|
||||||
* If profiling is off, then PROF_DUMP_FILENAME_LEN is 1, so we'll end up
|
|
||||||
* calling strncpy with a size of 0, which triggers a -Wstringop-truncation
|
|
||||||
* warning (strncpy can never actually be called in this case, since we bail out
|
|
||||||
* much earlier when config_prof is false). This function works around the
|
|
||||||
* warning to let us leave the warning on.
|
|
||||||
*/
|
|
||||||
static inline void
|
|
||||||
prof_strncpy(char *UNUSED dest, const char *UNUSED src, size_t UNUSED size) {
|
|
||||||
cassert(config_prof);
|
|
||||||
#ifdef JEMALLOC_PROF
|
|
||||||
strncpy(dest, src, size);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
prof_alloc_rollback(tsd_t *tsd, prof_tctx_t *tctx) {
|
prof_alloc_rollback(tsd_t *tsd, prof_tctx_t *tctx) {
|
||||||
cassert(config_prof);
|
cassert(config_prof);
|
||||||
@ -507,57 +482,9 @@ prof_getpid(void) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *
|
|
||||||
prof_dump_prefix_get(tsdn_t* tsdn) {
|
|
||||||
malloc_mutex_assert_owner(tsdn, &prof_dump_filename_mtx);
|
|
||||||
|
|
||||||
return prof_dump_prefix == NULL ? opt_prof_prefix : prof_dump_prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
prof_dump_prefix_is_empty(tsdn_t *tsdn) {
|
|
||||||
malloc_mutex_lock(tsdn, &prof_dump_filename_mtx);
|
|
||||||
bool ret = (prof_dump_prefix_get(tsdn)[0] == '\0');
|
|
||||||
malloc_mutex_unlock(tsdn, &prof_dump_filename_mtx);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DUMP_FILENAME_BUFSIZE (PATH_MAX + 1)
|
|
||||||
#define VSEQ_INVALID UINT64_C(0xffffffffffffffff)
|
|
||||||
static void
|
|
||||||
prof_dump_filename(tsd_t *tsd, char *filename, char v, uint64_t vseq) {
|
|
||||||
cassert(config_prof);
|
|
||||||
|
|
||||||
assert(tsd_reentrancy_level_get(tsd) == 0);
|
|
||||||
const char *prof_prefix = prof_dump_prefix_get(tsd_tsdn(tsd));
|
|
||||||
|
|
||||||
if (vseq != VSEQ_INVALID) {
|
|
||||||
/* "<prefix>.<pid>.<seq>.v<vseq>.heap" */
|
|
||||||
malloc_snprintf(filename, DUMP_FILENAME_BUFSIZE,
|
|
||||||
"%s.%d.%"FMTu64".%c%"FMTu64".heap",
|
|
||||||
prof_prefix, prof_getpid(), prof_dump_seq, v, vseq);
|
|
||||||
} else {
|
|
||||||
/* "<prefix>.<pid>.<seq>.<v>.heap" */
|
|
||||||
malloc_snprintf(filename, DUMP_FILENAME_BUFSIZE,
|
|
||||||
"%s.%d.%"FMTu64".%c.heap",
|
|
||||||
prof_prefix, prof_getpid(), prof_dump_seq, v);
|
|
||||||
}
|
|
||||||
prof_dump_seq++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
prof_get_default_filename(tsdn_t *tsdn, char *filename, uint64_t ind) {
|
|
||||||
malloc_mutex_lock(tsdn, &prof_dump_filename_mtx);
|
|
||||||
malloc_snprintf(filename, PROF_DUMP_FILENAME_LEN,
|
|
||||||
"%s.%d.%"FMTu64".json", prof_dump_prefix_get(tsdn), prof_getpid(),
|
|
||||||
ind);
|
|
||||||
malloc_mutex_unlock(tsdn, &prof_dump_filename_mtx);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
prof_fdump(void) {
|
prof_fdump(void) {
|
||||||
tsd_t *tsd;
|
tsd_t *tsd;
|
||||||
char filename[DUMP_FILENAME_BUFSIZE];
|
|
||||||
|
|
||||||
cassert(config_prof);
|
cassert(config_prof);
|
||||||
assert(opt_prof_final);
|
assert(opt_prof_final);
|
||||||
@ -567,12 +494,8 @@ prof_fdump(void) {
|
|||||||
}
|
}
|
||||||
tsd = tsd_fetch();
|
tsd = tsd_fetch();
|
||||||
assert(tsd_reentrancy_level_get(tsd) == 0);
|
assert(tsd_reentrancy_level_get(tsd) == 0);
|
||||||
assert(!prof_dump_prefix_is_empty(tsd_tsdn(tsd)));
|
|
||||||
|
|
||||||
malloc_mutex_lock(tsd_tsdn(tsd), &prof_dump_filename_mtx);
|
prof_fdump_impl(tsd);
|
||||||
prof_dump_filename(tsd, filename, 'f', VSEQ_INVALID);
|
|
||||||
malloc_mutex_unlock(tsd_tsdn(tsd), &prof_dump_filename_mtx);
|
|
||||||
prof_dump(tsd, false, filename, opt_prof_leak);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
@ -582,31 +505,6 @@ prof_idump_accum_init(void) {
|
|||||||
return counter_accum_init(&prof_idump_accumulated, prof_interval);
|
return counter_accum_init(&prof_idump_accumulated, prof_interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
prof_dump_prefix_set(tsdn_t *tsdn, const char *prefix) {
|
|
||||||
cassert(config_prof);
|
|
||||||
ctl_mtx_assert_held(tsdn);
|
|
||||||
malloc_mutex_lock(tsdn, &prof_dump_filename_mtx);
|
|
||||||
if (prof_dump_prefix == NULL) {
|
|
||||||
malloc_mutex_unlock(tsdn, &prof_dump_filename_mtx);
|
|
||||||
/* Everything is still guarded by ctl_mtx. */
|
|
||||||
char *buffer = base_alloc(tsdn, prof_base,
|
|
||||||
PROF_DUMP_FILENAME_LEN, QUANTUM);
|
|
||||||
if (buffer == NULL) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
malloc_mutex_lock(tsdn, &prof_dump_filename_mtx);
|
|
||||||
prof_dump_prefix = buffer;
|
|
||||||
}
|
|
||||||
assert(prof_dump_prefix != NULL);
|
|
||||||
|
|
||||||
prof_strncpy(prof_dump_prefix, prefix, PROF_DUMP_FILENAME_LEN - 1);
|
|
||||||
prof_dump_prefix[PROF_DUMP_FILENAME_LEN - 1] = '\0';
|
|
||||||
malloc_mutex_unlock(tsdn, &prof_dump_filename_mtx);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
prof_idump(tsdn_t *tsdn) {
|
prof_idump(tsdn_t *tsdn) {
|
||||||
tsd_t *tsd;
|
tsd_t *tsd;
|
||||||
@ -631,16 +529,7 @@ prof_idump(tsdn_t *tsdn) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
malloc_mutex_lock(tsd_tsdn(tsd), &prof_dump_filename_mtx);
|
prof_idump_impl(tsd);
|
||||||
if (prof_dump_prefix_get(tsd_tsdn(tsd))[0] == '\0') {
|
|
||||||
malloc_mutex_unlock(tsd_tsdn(tsd), &prof_dump_filename_mtx);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
char filename[PATH_MAX + 1];
|
|
||||||
prof_dump_filename(tsd, filename, 'i', prof_dump_iseq);
|
|
||||||
prof_dump_iseq++;
|
|
||||||
malloc_mutex_unlock(tsd_tsdn(tsd), &prof_dump_filename_mtx);
|
|
||||||
prof_dump(tsd, false, filename, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -651,20 +540,8 @@ prof_mdump(tsd_t *tsd, const char *filename) {
|
|||||||
if (!opt_prof || !prof_booted) {
|
if (!opt_prof || !prof_booted) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
char filename_buf[DUMP_FILENAME_BUFSIZE];
|
|
||||||
if (filename == NULL) {
|
return prof_mdump_impl(tsd, filename);
|
||||||
/* No filename specified, so automatically generate one. */
|
|
||||||
malloc_mutex_lock(tsd_tsdn(tsd), &prof_dump_filename_mtx);
|
|
||||||
if (prof_dump_prefix_get(tsd_tsdn(tsd))[0] == '\0') {
|
|
||||||
malloc_mutex_unlock(tsd_tsdn(tsd), &prof_dump_filename_mtx);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
prof_dump_filename(tsd, filename_buf, 'm', prof_dump_mseq);
|
|
||||||
prof_dump_mseq++;
|
|
||||||
malloc_mutex_unlock(tsd_tsdn(tsd), &prof_dump_filename_mtx);
|
|
||||||
filename = filename_buf;
|
|
||||||
}
|
|
||||||
return prof_dump(tsd, true, filename, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -691,16 +568,7 @@ prof_gdump(tsdn_t *tsdn) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
malloc_mutex_lock(tsdn, &prof_dump_filename_mtx);
|
prof_gdump_impl(tsd);
|
||||||
if (prof_dump_prefix_get(tsdn)[0] == '\0') {
|
|
||||||
malloc_mutex_unlock(tsdn, &prof_dump_filename_mtx);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
char filename[DUMP_FILENAME_BUFSIZE];
|
|
||||||
prof_dump_filename(tsd, filename, 'u', prof_dump_useq);
|
|
||||||
prof_dump_useq++;
|
|
||||||
malloc_mutex_unlock(tsdn, &prof_dump_filename_mtx);
|
|
||||||
prof_dump(tsd, false, filename, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t
|
static uint64_t
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "jemalloc/internal/mutex.h"
|
#include "jemalloc/internal/mutex.h"
|
||||||
#include "jemalloc/internal/prof_data.h"
|
#include "jemalloc/internal/prof_data.h"
|
||||||
#include "jemalloc/internal/prof_log.h"
|
#include "jemalloc/internal/prof_log.h"
|
||||||
|
#include "jemalloc/internal/prof_sys.h"
|
||||||
|
|
||||||
bool opt_prof_log = false;
|
bool opt_prof_log = false;
|
||||||
typedef enum prof_logging_state_e prof_logging_state_t;
|
typedef enum prof_logging_state_e prof_logging_state_t;
|
||||||
|
158
src/prof_sys.c
158
src/prof_sys.c
@ -2,9 +2,22 @@
|
|||||||
#include "jemalloc/internal/jemalloc_preamble.h"
|
#include "jemalloc/internal/jemalloc_preamble.h"
|
||||||
#include "jemalloc/internal/jemalloc_internal_includes.h"
|
#include "jemalloc/internal/jemalloc_internal_includes.h"
|
||||||
|
|
||||||
|
#include "jemalloc/internal/ctl.h"
|
||||||
#include "jemalloc/internal/prof_data.h"
|
#include "jemalloc/internal/prof_data.h"
|
||||||
#include "jemalloc/internal/prof_sys.h"
|
#include "jemalloc/internal/prof_sys.h"
|
||||||
|
|
||||||
|
malloc_mutex_t prof_dump_filename_mtx;
|
||||||
|
|
||||||
|
static uint64_t prof_dump_seq;
|
||||||
|
static uint64_t prof_dump_iseq;
|
||||||
|
static uint64_t prof_dump_mseq;
|
||||||
|
static uint64_t prof_dump_useq;
|
||||||
|
|
||||||
|
static char *prof_dump_prefix = NULL;
|
||||||
|
|
||||||
|
/* The fallback allocator profiling functionality will use. */
|
||||||
|
base_t *prof_base;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
prof_sys_thread_name_read_impl(char *buf, size_t limit) {
|
prof_sys_thread_name_read_impl(char *buf, size_t limit) {
|
||||||
#ifdef JEMALLOC_HAVE_PTHREAD_SETNAME_NP
|
#ifdef JEMALLOC_HAVE_PTHREAD_SETNAME_NP
|
||||||
@ -25,3 +38,148 @@ prof_sys_thread_name_fetch(tsd_t *tsd) {
|
|||||||
}
|
}
|
||||||
#undef THREAD_NAME_MAX_LEN
|
#undef THREAD_NAME_MAX_LEN
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If profiling is off, then PROF_DUMP_FILENAME_LEN is 1, so we'll end up
|
||||||
|
* calling strncpy with a size of 0, which triggers a -Wstringop-truncation
|
||||||
|
* warning (strncpy can never actually be called in this case, since we bail out
|
||||||
|
* much earlier when config_prof is false). This function works around the
|
||||||
|
* warning to let us leave the warning on.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
prof_strncpy(char *UNUSED dest, const char *UNUSED src, size_t UNUSED size) {
|
||||||
|
cassert(config_prof);
|
||||||
|
#ifdef JEMALLOC_PROF
|
||||||
|
strncpy(dest, src, size);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
prof_dump_prefix_get(tsdn_t* tsdn) {
|
||||||
|
malloc_mutex_assert_owner(tsdn, &prof_dump_filename_mtx);
|
||||||
|
|
||||||
|
return prof_dump_prefix == NULL ? opt_prof_prefix : prof_dump_prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
prof_dump_prefix_is_empty(tsdn_t *tsdn) {
|
||||||
|
malloc_mutex_lock(tsdn, &prof_dump_filename_mtx);
|
||||||
|
bool ret = (prof_dump_prefix_get(tsdn)[0] == '\0');
|
||||||
|
malloc_mutex_unlock(tsdn, &prof_dump_filename_mtx);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DUMP_FILENAME_BUFSIZE (PATH_MAX + 1)
|
||||||
|
#define VSEQ_INVALID UINT64_C(0xffffffffffffffff)
|
||||||
|
static void
|
||||||
|
prof_dump_filename(tsd_t *tsd, char *filename, char v, uint64_t vseq) {
|
||||||
|
cassert(config_prof);
|
||||||
|
|
||||||
|
assert(tsd_reentrancy_level_get(tsd) == 0);
|
||||||
|
const char *prof_prefix = prof_dump_prefix_get(tsd_tsdn(tsd));
|
||||||
|
|
||||||
|
if (vseq != VSEQ_INVALID) {
|
||||||
|
/* "<prefix>.<pid>.<seq>.v<vseq>.heap" */
|
||||||
|
malloc_snprintf(filename, DUMP_FILENAME_BUFSIZE,
|
||||||
|
"%s.%d.%"FMTu64".%c%"FMTu64".heap",
|
||||||
|
prof_prefix, prof_getpid(), prof_dump_seq, v, vseq);
|
||||||
|
} else {
|
||||||
|
/* "<prefix>.<pid>.<seq>.<v>.heap" */
|
||||||
|
malloc_snprintf(filename, DUMP_FILENAME_BUFSIZE,
|
||||||
|
"%s.%d.%"FMTu64".%c.heap",
|
||||||
|
prof_prefix, prof_getpid(), prof_dump_seq, v);
|
||||||
|
}
|
||||||
|
prof_dump_seq++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
prof_get_default_filename(tsdn_t *tsdn, char *filename, uint64_t ind) {
|
||||||
|
malloc_mutex_lock(tsdn, &prof_dump_filename_mtx);
|
||||||
|
malloc_snprintf(filename, PROF_DUMP_FILENAME_LEN,
|
||||||
|
"%s.%d.%"FMTu64".json", prof_dump_prefix_get(tsdn), prof_getpid(),
|
||||||
|
ind);
|
||||||
|
malloc_mutex_unlock(tsdn, &prof_dump_filename_mtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
prof_fdump_impl(tsd_t *tsd) {
|
||||||
|
char filename[DUMP_FILENAME_BUFSIZE];
|
||||||
|
|
||||||
|
assert(!prof_dump_prefix_is_empty(tsd_tsdn(tsd)));
|
||||||
|
malloc_mutex_lock(tsd_tsdn(tsd), &prof_dump_filename_mtx);
|
||||||
|
prof_dump_filename(tsd, filename, 'f', VSEQ_INVALID);
|
||||||
|
malloc_mutex_unlock(tsd_tsdn(tsd), &prof_dump_filename_mtx);
|
||||||
|
prof_dump(tsd, false, filename, opt_prof_leak);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
prof_dump_prefix_set(tsdn_t *tsdn, const char *prefix) {
|
||||||
|
cassert(config_prof);
|
||||||
|
ctl_mtx_assert_held(tsdn);
|
||||||
|
malloc_mutex_lock(tsdn, &prof_dump_filename_mtx);
|
||||||
|
if (prof_dump_prefix == NULL) {
|
||||||
|
malloc_mutex_unlock(tsdn, &prof_dump_filename_mtx);
|
||||||
|
/* Everything is still guarded by ctl_mtx. */
|
||||||
|
char *buffer = base_alloc(tsdn, prof_base,
|
||||||
|
PROF_DUMP_FILENAME_LEN, QUANTUM);
|
||||||
|
if (buffer == NULL) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
malloc_mutex_lock(tsdn, &prof_dump_filename_mtx);
|
||||||
|
prof_dump_prefix = buffer;
|
||||||
|
}
|
||||||
|
assert(prof_dump_prefix != NULL);
|
||||||
|
|
||||||
|
prof_strncpy(prof_dump_prefix, prefix, PROF_DUMP_FILENAME_LEN - 1);
|
||||||
|
prof_dump_prefix[PROF_DUMP_FILENAME_LEN - 1] = '\0';
|
||||||
|
malloc_mutex_unlock(tsdn, &prof_dump_filename_mtx);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
prof_idump_impl(tsd_t *tsd) {
|
||||||
|
malloc_mutex_lock(tsd_tsdn(tsd), &prof_dump_filename_mtx);
|
||||||
|
if (prof_dump_prefix_get(tsd_tsdn(tsd))[0] == '\0') {
|
||||||
|
malloc_mutex_unlock(tsd_tsdn(tsd), &prof_dump_filename_mtx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
char filename[PATH_MAX + 1];
|
||||||
|
prof_dump_filename(tsd, filename, 'i', prof_dump_iseq);
|
||||||
|
prof_dump_iseq++;
|
||||||
|
malloc_mutex_unlock(tsd_tsdn(tsd), &prof_dump_filename_mtx);
|
||||||
|
prof_dump(tsd, false, filename, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
prof_mdump_impl(tsd_t *tsd, const char *filename) {
|
||||||
|
char filename_buf[DUMP_FILENAME_BUFSIZE];
|
||||||
|
if (filename == NULL) {
|
||||||
|
/* No filename specified, so automatically generate one. */
|
||||||
|
malloc_mutex_lock(tsd_tsdn(tsd), &prof_dump_filename_mtx);
|
||||||
|
if (prof_dump_prefix_get(tsd_tsdn(tsd))[0] == '\0') {
|
||||||
|
malloc_mutex_unlock(tsd_tsdn(tsd), &prof_dump_filename_mtx);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
prof_dump_filename(tsd, filename_buf, 'm', prof_dump_mseq);
|
||||||
|
prof_dump_mseq++;
|
||||||
|
malloc_mutex_unlock(tsd_tsdn(tsd), &prof_dump_filename_mtx);
|
||||||
|
filename = filename_buf;
|
||||||
|
}
|
||||||
|
return prof_dump(tsd, true, filename, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
prof_gdump_impl(tsd_t *tsd) {
|
||||||
|
tsdn_t *tsdn = tsd_tsdn(tsd);
|
||||||
|
malloc_mutex_lock(tsdn, &prof_dump_filename_mtx);
|
||||||
|
if (prof_dump_prefix_get(tsdn)[0] == '\0') {
|
||||||
|
malloc_mutex_unlock(tsdn, &prof_dump_filename_mtx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
char filename[DUMP_FILENAME_BUFSIZE];
|
||||||
|
prof_dump_filename(tsd, filename, 'u', prof_dump_useq);
|
||||||
|
prof_dump_useq++;
|
||||||
|
malloc_mutex_unlock(tsdn, &prof_dump_filename_mtx);
|
||||||
|
prof_dump(tsd, false, filename, false);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user