mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-05-04 22:49:32 +03:00
add argument pointer to the register output routine
This commit is contained in:
parent
65f4f5144b
commit
f92a2a7264
2 changed files with 24 additions and 17 deletions
|
@ -111,8 +111,8 @@ mi_decl_export size_t mi_good_size(size_t size) mi_attr_noexcept;
|
||||||
typedef void (mi_deferred_free_fun)(bool force, unsigned long long heartbeat);
|
typedef void (mi_deferred_free_fun)(bool force, unsigned long long heartbeat);
|
||||||
mi_decl_export void mi_register_deferred_free(mi_deferred_free_fun* deferred_free) mi_attr_noexcept;
|
mi_decl_export void mi_register_deferred_free(mi_deferred_free_fun* deferred_free) mi_attr_noexcept;
|
||||||
|
|
||||||
typedef void (mi_output_fun)(const char* msg);
|
typedef void (mi_output_fun)(const char* msg, void* arg);
|
||||||
mi_decl_export void mi_register_output(mi_output_fun* out) mi_attr_noexcept;
|
mi_decl_export void mi_register_output(mi_output_fun* out, void* arg) mi_attr_noexcept;
|
||||||
|
|
||||||
mi_decl_export void mi_collect(bool force) mi_attr_noexcept;
|
mi_decl_export void mi_collect(bool force) mi_attr_noexcept;
|
||||||
mi_decl_export int mi_version(void) mi_attr_noexcept;
|
mi_decl_export int mi_version(void) mi_attr_noexcept;
|
||||||
|
|
|
@ -140,7 +140,8 @@ void mi_option_disable(mi_option_t option) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void mi_out_stderr(const char* msg) {
|
static void mi_out_stderr(const char* msg, void* arg) {
|
||||||
|
UNUSED(arg);
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// on windows with redirection, the C runtime cannot handle locale dependent output
|
// on windows with redirection, the C runtime cannot handle locale dependent output
|
||||||
// after the main thread closes so we use direct console output.
|
// after the main thread closes so we use direct console output.
|
||||||
|
@ -160,7 +161,8 @@ static void mi_out_stderr(const char* msg) {
|
||||||
static char out_buf[MI_MAX_DELAY_OUTPUT+1];
|
static char out_buf[MI_MAX_DELAY_OUTPUT+1];
|
||||||
static _Atomic(uintptr_t) out_len;
|
static _Atomic(uintptr_t) out_len;
|
||||||
|
|
||||||
static void mi_out_buf(const char* msg) {
|
static void mi_out_buf(const char* msg, void* arg) {
|
||||||
|
UNUSED(arg);
|
||||||
if (msg==NULL) return;
|
if (msg==NULL) return;
|
||||||
if (mi_atomic_read_relaxed(&out_len)>=MI_MAX_DELAY_OUTPUT) return;
|
if (mi_atomic_read_relaxed(&out_len)>=MI_MAX_DELAY_OUTPUT) return;
|
||||||
size_t n = strlen(msg);
|
size_t n = strlen(msg);
|
||||||
|
@ -175,14 +177,14 @@ static void mi_out_buf(const char* msg) {
|
||||||
memcpy(&out_buf[start], msg, n);
|
memcpy(&out_buf[start], msg, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mi_out_buf_flush(mi_output_fun* out, bool no_more_buf) {
|
static void mi_out_buf_flush(mi_output_fun* out, bool no_more_buf, void* arg) {
|
||||||
if (out==NULL) return;
|
if (out==NULL) return;
|
||||||
// claim (if `no_more_buf == true`, no more output will be added after this point)
|
// claim (if `no_more_buf == true`, no more output will be added after this point)
|
||||||
size_t count = mi_atomic_addu(&out_len, (no_more_buf ? MI_MAX_DELAY_OUTPUT : 1));
|
size_t count = mi_atomic_addu(&out_len, (no_more_buf ? MI_MAX_DELAY_OUTPUT : 1));
|
||||||
// and output the current contents
|
// and output the current contents
|
||||||
if (count>MI_MAX_DELAY_OUTPUT) count = MI_MAX_DELAY_OUTPUT;
|
if (count>MI_MAX_DELAY_OUTPUT) count = MI_MAX_DELAY_OUTPUT;
|
||||||
out_buf[count] = 0;
|
out_buf[count] = 0;
|
||||||
out(out_buf);
|
out(out_buf,arg);
|
||||||
if (!no_more_buf) {
|
if (!no_more_buf) {
|
||||||
out_buf[count] = '\n'; // if continue with the buffer, insert a newline
|
out_buf[count] = '\n'; // if continue with the buffer, insert a newline
|
||||||
}
|
}
|
||||||
|
@ -191,9 +193,9 @@ static void mi_out_buf_flush(mi_output_fun* out, bool no_more_buf) {
|
||||||
|
|
||||||
// Once this module is loaded, switch to this routine
|
// Once this module is loaded, switch to this routine
|
||||||
// which outputs to stderr and the delayed output buffer.
|
// which outputs to stderr and the delayed output buffer.
|
||||||
static void mi_out_buf_stderr(const char* msg) {
|
static void mi_out_buf_stderr(const char* msg, void* arg) {
|
||||||
mi_out_stderr(msg);
|
mi_out_stderr(msg,arg);
|
||||||
mi_out_buf(msg);
|
mi_out_buf(msg,arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -206,21 +208,25 @@ static void mi_out_buf_stderr(const char* msg) {
|
||||||
// For now, don't register output from multiple threads.
|
// For now, don't register output from multiple threads.
|
||||||
#pragma warning(suppress:4180)
|
#pragma warning(suppress:4180)
|
||||||
static mi_output_fun* volatile mi_out_default; // = NULL
|
static mi_output_fun* volatile mi_out_default; // = NULL
|
||||||
|
static volatile _Atomic(void*) mi_out_arg; // = NULL
|
||||||
|
|
||||||
static mi_output_fun* mi_out_get_default(void) {
|
static mi_output_fun* mi_out_get_default(void** parg) {
|
||||||
|
if (parg != NULL) { *parg = mi_atomic_read_ptr(&mi_out_arg); }
|
||||||
mi_output_fun* out = mi_out_default;
|
mi_output_fun* out = mi_out_default;
|
||||||
return (out == NULL ? &mi_out_buf : out);
|
return (out == NULL ? &mi_out_buf : out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mi_register_output(mi_output_fun* out) mi_attr_noexcept {
|
void mi_register_output(mi_output_fun* out, void* arg) mi_attr_noexcept {
|
||||||
mi_out_default = (out == NULL ? &mi_out_stderr : out); // stop using the delayed output buffer
|
mi_out_default = (out == NULL ? &mi_out_stderr : out); // stop using the delayed output buffer
|
||||||
if (out!=NULL) mi_out_buf_flush(out,true); // output all the delayed output now
|
mi_atomic_write_ptr(&mi_out_arg, arg);
|
||||||
|
if (out!=NULL) mi_out_buf_flush(out,true,arg); // output all the delayed output now
|
||||||
}
|
}
|
||||||
|
|
||||||
// add stderr to the delayed output after the module is loaded
|
// add stderr to the delayed output after the module is loaded
|
||||||
static void mi_add_stderr_output() {
|
static void mi_add_stderr_output() {
|
||||||
mi_out_buf_flush(&mi_out_stderr, false); // flush current contents to stderr
|
mi_assert_internal(mi_out_default == NULL);
|
||||||
mi_out_default = &mi_out_buf_stderr; // and add stderr to the delayed output
|
mi_out_buf_flush(&mi_out_stderr, false, NULL); // flush current contents to stderr
|
||||||
|
mi_out_default = &mi_out_buf_stderr; // and add stderr to the delayed output
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
|
@ -234,10 +240,11 @@ static mi_decl_thread bool recurse = false;
|
||||||
|
|
||||||
void _mi_fputs(mi_output_fun* out, const char* prefix, const char* message) {
|
void _mi_fputs(mi_output_fun* out, const char* prefix, const char* message) {
|
||||||
if (recurse) return;
|
if (recurse) return;
|
||||||
if (out==NULL || (FILE*)out==stdout || (FILE*)out==stderr) out = mi_out_get_default();
|
void* arg = NULL;
|
||||||
|
if (out==NULL || (FILE*)out==stdout || (FILE*)out==stderr) out = mi_out_get_default(&arg);
|
||||||
recurse = true;
|
recurse = true;
|
||||||
if (prefix != NULL) out(prefix);
|
if (prefix != NULL) out(prefix,arg);
|
||||||
out(message);
|
out(message,arg);
|
||||||
recurse = false;
|
recurse = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue