Make buffered writer an independent module

This commit is contained in:
Yinan Zhang 2020-01-09 16:36:09 -08:00
parent 6b6b4709b3
commit 6d8e616902
13 changed files with 76 additions and 57 deletions

View File

@ -101,6 +101,7 @@ C_SRCS := $(srcroot)src/jemalloc.c \
$(srcroot)src/bin.c \ $(srcroot)src/bin.c \
$(srcroot)src/bin_info.c \ $(srcroot)src/bin_info.c \
$(srcroot)src/bitmap.c \ $(srcroot)src/bitmap.c \
$(srcroot)src/buf_writer.c \
$(srcroot)src/ckh.c \ $(srcroot)src/ckh.c \
$(srcroot)src/ctl.c \ $(srcroot)src/ctl.c \
$(srcroot)src/div.c \ $(srcroot)src/div.c \

View File

@ -0,0 +1,24 @@
#ifndef JEMALLOC_INTERNAL_BUF_WRITER_H
#define JEMALLOC_INTERNAL_BUF_WRITER_H
/*
* Note: when using the buffered writer, cbopaque is passed to write_cb only
* when the buffer is flushed. It would make a difference if cbopaque points
* to something that's changing for each write_cb call, or something that
* affects write_cb in a way dependent on the content of the output string.
* However, the most typical usage case in practice is that cbopaque points to
* some "option like" content for the write_cb, so it doesn't matter.
*/
typedef struct {
void (*write_cb)(void *, const char *);
void *cbopaque;
char *buf;
size_t buf_size; /* must be one less than the capacity of buf array */
size_t buf_end;
} buf_write_arg_t;
void buf_write_flush(buf_write_arg_t *arg);
void buf_write_cb(void *buf_write_arg, const char *s);
#endif /* JEMALLOC_INTERNAL_BUF_WRITER_H */

View File

@ -40,6 +40,7 @@
*/ */
#define MALLOC_PRINTF_BUFSIZE 4096 #define MALLOC_PRINTF_BUFSIZE 4096
void wrtmessage(void *cbopaque, const char *s);
int buferror(int err, char *buf, size_t buflen); int buferror(int err, char *buf, size_t buflen);
uintmax_t malloc_strtoumax(const char *restrict nptr, char **restrict endptr, uintmax_t malloc_strtoumax(const char *restrict nptr, char **restrict endptr,
int base); int base);
@ -99,29 +100,4 @@ malloc_read_fd(int fd, void *buf, size_t count) {
return (ssize_t)result; return (ssize_t)result;
} }
/******************************************************************************/
/*
* The rest is buffered writing utility.
*
* The only difference when using the buffered writer is that cbopaque is
* passed to write_cb only when the buffer is flushed. It would make a
* difference if cbopaque points to something that's changing for each write_cb
* call, or something that affects write_cb in a way dependent on the content
* of the output string. However, the most typical usage case in practice is
* that cbopaque points to some "option like" content for the write_cb, so it
* doesn't matter.
*/
typedef struct {
void (*write_cb)(void *, const char *);
void *cbopaque;
char *buf;
size_t buf_size; /* must be one less than the capacity of buf array */
size_t buf_end;
} buf_write_arg_t;
void buf_write_flush(buf_write_arg_t *arg);
void buf_write_cb(void *buf_write_arg, const char *s);
#endif /* JEMALLOC_INTERNAL_MALLOC_IO_H */ #endif /* JEMALLOC_INTERNAL_MALLOC_IO_H */

View File

@ -41,6 +41,7 @@
<ClCompile Include="..\..\..\..\src\bin.c" /> <ClCompile Include="..\..\..\..\src\bin.c" />
<ClCompile Include="..\..\..\..\src\bin_info.c" /> <ClCompile Include="..\..\..\..\src\bin_info.c" />
<ClCompile Include="..\..\..\..\src\bitmap.c" /> <ClCompile Include="..\..\..\..\src\bitmap.c" />
<ClCompile Include="..\..\..\..\src\buf_writer.c" />
<ClCompile Include="..\..\..\..\src\ckh.c" /> <ClCompile Include="..\..\..\..\src\ckh.c" />
<ClCompile Include="..\..\..\..\src\ctl.c" /> <ClCompile Include="..\..\..\..\src\ctl.c" />
<ClCompile Include="..\..\..\..\src\div.c" /> <ClCompile Include="..\..\..\..\src\div.c" />

View File

@ -22,6 +22,9 @@
<ClCompile Include="..\..\..\..\src\bitmap.c"> <ClCompile Include="..\..\..\..\src\bitmap.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\..\src\buf_writer.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\ckh.c"> <ClCompile Include="..\..\..\..\src\ckh.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>

View File

@ -41,6 +41,7 @@
<ClCompile Include="..\..\..\..\src\bin.c" /> <ClCompile Include="..\..\..\..\src\bin.c" />
<ClCompile Include="..\..\..\..\src\bin_info.c" /> <ClCompile Include="..\..\..\..\src\bin_info.c" />
<ClCompile Include="..\..\..\..\src\bitmap.c" /> <ClCompile Include="..\..\..\..\src\bitmap.c" />
<ClCompile Include="..\..\..\..\src\buf_writer.c" />
<ClCompile Include="..\..\..\..\src\ckh.c" /> <ClCompile Include="..\..\..\..\src\ckh.c" />
<ClCompile Include="..\..\..\..\src\ctl.c" /> <ClCompile Include="..\..\..\..\src\ctl.c" />
<ClCompile Include="..\..\..\..\src\div.c" /> <ClCompile Include="..\..\..\..\src\div.c" />

View File

@ -22,6 +22,9 @@
<ClCompile Include="..\..\..\..\src\bitmap.c"> <ClCompile Include="..\..\..\..\src\bitmap.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\..\src\buf_writer.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\ckh.c"> <ClCompile Include="..\..\..\..\src\ckh.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>

36
src/buf_writer.c Normal file
View File

@ -0,0 +1,36 @@
#define JEMALLOC_BUF_WRITER_C_
#include "jemalloc/internal/jemalloc_preamble.h"
#include "jemalloc/internal/jemalloc_internal_includes.h"
#include "jemalloc/internal/buf_writer.h"
#include "jemalloc/internal/malloc_io.h"
void
buf_write_flush(buf_write_arg_t *arg) {
assert(arg->buf_end <= arg->buf_size);
arg->buf[arg->buf_end] = '\0';
if (arg->write_cb == NULL) {
arg->write_cb = je_malloc_message != NULL ?
je_malloc_message : wrtmessage;
}
arg->write_cb(arg->cbopaque, arg->buf);
arg->buf_end = 0;
}
void
buf_write_cb(void *buf_write_arg, const char *s) {
buf_write_arg_t *arg = (buf_write_arg_t *)buf_write_arg;
size_t i, slen, n, s_remain, buf_remain;
assert(arg->buf_end <= arg->buf_size);
for (i = 0, slen = strlen(s); i < slen; i += n) {
if (arg->buf_end == arg->buf_size) {
buf_write_flush(arg);
}
s_remain = slen - i;
buf_remain = arg->buf_size - arg->buf_end;
n = s_remain < buf_remain ? s_remain : buf_remain;
memcpy(arg->buf + arg->buf_end, s + i, n);
arg->buf_end += n;
}
assert(i == slen);
}

View File

@ -4,6 +4,7 @@
#include "jemalloc/internal/assert.h" #include "jemalloc/internal/assert.h"
#include "jemalloc/internal/atomic.h" #include "jemalloc/internal/atomic.h"
#include "jemalloc/internal/buf_writer.h"
#include "jemalloc/internal/ctl.h" #include "jemalloc/internal/ctl.h"
#include "jemalloc/internal/extent_dss.h" #include "jemalloc/internal/extent_dss.h"
#include "jemalloc/internal/extent_mmap.h" #include "jemalloc/internal/extent_mmap.h"

View File

@ -53,7 +53,6 @@
/******************************************************************************/ /******************************************************************************/
/* Function prototypes for non-inline static functions. */ /* Function prototypes for non-inline static functions. */
static void wrtmessage(void *cbopaque, const char *s);
#define U2S_BUFSIZE ((1U << (LG_SIZEOF_INTMAX_T + 3)) + 1) #define U2S_BUFSIZE ((1U << (LG_SIZEOF_INTMAX_T + 3)) + 1)
static char *u2s(uintmax_t x, unsigned base, bool uppercase, char *s, static char *u2s(uintmax_t x, unsigned base, bool uppercase, char *s,
size_t *slen_p); size_t *slen_p);
@ -68,7 +67,7 @@ static char *x2s(uintmax_t x, bool alt_form, bool uppercase, char *s,
/******************************************************************************/ /******************************************************************************/
/* malloc_message() setup. */ /* malloc_message() setup. */
static void void
wrtmessage(void *cbopaque, const char *s) { wrtmessage(void *cbopaque, const char *s) {
malloc_write_fd(STDERR_FILENO, s, strlen(s)); malloc_write_fd(STDERR_FILENO, s, strlen(s));
} }
@ -664,36 +663,6 @@ malloc_printf(const char *format, ...) {
va_end(ap); va_end(ap);
} }
void
buf_write_flush(buf_write_arg_t *arg) {
assert(arg->buf_end <= arg->buf_size);
arg->buf[arg->buf_end] = '\0';
if (arg->write_cb == NULL) {
arg->write_cb = je_malloc_message != NULL ?
je_malloc_message : wrtmessage;
}
arg->write_cb(arg->cbopaque, arg->buf);
arg->buf_end = 0;
}
void
buf_write_cb(void *buf_write_arg, const char *s) {
buf_write_arg_t *arg = (buf_write_arg_t *)buf_write_arg;
size_t i, slen, n, s_remain, buf_remain;
assert(arg->buf_end <= arg->buf_size);
for (i = 0, slen = strlen(s); i < slen; i += n) {
if (arg->buf_end == arg->buf_size) {
buf_write_flush(arg);
}
s_remain = slen - i;
buf_remain = arg->buf_size - arg->buf_end;
n = s_remain < buf_remain ? s_remain : buf_remain;
memcpy(arg->buf + arg->buf_end, s + i, n);
arg->buf_end += n;
}
assert(i == slen);
}
/* /*
* Restore normal assertion macros, in order to make it possible to compile all * Restore normal assertion macros, in order to make it possible to compile all
* C files as a single concatenation. * C files as a single concatenation.

View File

@ -3,6 +3,7 @@
#include "jemalloc/internal/jemalloc_internal_includes.h" #include "jemalloc/internal/jemalloc_internal_includes.h"
#include "jemalloc/internal/assert.h" #include "jemalloc/internal/assert.h"
#include "jemalloc/internal/buf_writer.h"
#include "jemalloc/internal/ckh.h" #include "jemalloc/internal/ckh.h"
#include "jemalloc/internal/emitter.h" #include "jemalloc/internal/emitter.h"
#include "jemalloc/internal/hash.h" #include "jemalloc/internal/hash.h"

View File

@ -3,6 +3,7 @@
#include "jemalloc/internal/jemalloc_internal_includes.h" #include "jemalloc/internal/jemalloc_internal_includes.h"
#include "jemalloc/internal/assert.h" #include "jemalloc/internal/assert.h"
#include "jemalloc/internal/buf_writer.h"
#include "jemalloc/internal/emitter.h" #include "jemalloc/internal/emitter.h"
#include "jemalloc/internal/prof_data.h" #include "jemalloc/internal/prof_data.h"
#include "jemalloc/internal/prof_recent.h" #include "jemalloc/internal/prof_recent.h"

View File

@ -1,5 +1,7 @@
#include "test/jemalloc_test.h" #include "test/jemalloc_test.h"
#include "jemalloc/internal/buf_writer.h"
#define TEST_BUF_SIZE 16 #define TEST_BUF_SIZE 16
#define UNIT_MAX (TEST_BUF_SIZE * 3) #define UNIT_MAX (TEST_BUF_SIZE * 3)