morita
morit****@razil*****
2008年 9月 25日 (木) 23:07:48 JST
森です。
提案ありがとうございます。
ビルド時にオプションを指定したときに限って動的にアロケータを指定可能にするのであれば、
(オプションを指定しない限り)性能上のデメリットが発生しないので、アリかなぁと思いましたです。
Kouhei Sutou さんは書きました:
> 須藤です。
>
> 現在はビルド時に--enable-fmallocオプションを指定することで
> fail mallocの機能を有効がなり、sen_malloc()の代わりに
> sen_fail_malloc()が使用されるようになります。もし、実行
> 時に動的にsen_malloc()の代わりの関数を変更できるとテストが書
> きやすくなる気がしています。(特定の処理の間だけfailするよう
> にするとかが簡単にできそう)
>
>
> 実装のイメージはパッチの通りなのですが、これに加えて
> sen_ctx_set_malloc_func()のようなアクセサがあるとよいのかと
> 思っています。
>
> 速度の事もあるので、ビルド時のオプションで有効・無効を切り替
> えるようにした方がよいのもしれません。
> (ほんとはベンチマークをとってから言った方がよいのですが。。。)
>
>
> どうでしょうか?
>
> -------------- next part --------------
> Index: lib/ctx.c
> ===================================================================
> --- lib/ctx.c (リビジョン 1138)
> +++ lib/ctx.c (作業コピー)
> @@ -207,6 +207,17 @@
> ctx->impl->encoding = ctx->encoding;
> ctx->impl->lifoseg = -1;
> ctx->impl->currseg = -1;
> +#ifdef USE_FAIL_MALLOC
> + ctx->impl->malloc_func = sen_malloc_fail;
> + ctx->impl->calloc_func = sen_calloc_fail;
> + ctx->impl->realloc_func = sen_realloc_fail;
> + ctx->impl->strdup_func = sen_strdup_fail;
> +#else
> + ctx->impl->malloc_func = sen_malloc_default;
> + ctx->impl->calloc_func = sen_calloc_default;
> + ctx->impl->realloc_func = sen_realloc_default;
> + ctx->impl->strdup_func = sen_strdup_default;
> +#endif
> ctx->impl->db = NULL;
> ctx->impl->phs = NIL;
> ctx->impl->code = NIL;
> @@ -880,8 +891,48 @@
> }
>
> void *
> -sen_malloc(sen_ctx *ctx, size_t size, const char* file, int line)
> +sen_malloc(sen_ctx *ctx, size_t size, const char* file, int line, const char *func)
> {
> + if (ctx && ctx->impl && ctx->impl->malloc_func) {
> + return ctx->impl->malloc_func(ctx, size, file, line, func);
> + } else {
> + return sen_malloc_default(ctx, size, file, line, func);
> + }
> +}
> +
> +void *
> +sen_calloc(sen_ctx *ctx, size_t size, const char* file, int line, const char *func)
> +{
> + if (ctx && ctx->impl && ctx->impl->calloc_func) {
> + return ctx->impl->calloc_func(ctx, size, file, line, func);
> + } else {
> + return sen_calloc_default(ctx, size, file, line, func);
> + }
> +}
> +
> +void *
> +sen_realloc(sen_ctx *ctx, void *ptr, size_t size, const char* file, int line, const char *func)
> +{
> + if (ctx && ctx->impl && ctx->impl->realloc_func) {
> + return ctx->impl->realloc_func(ctx, ptr, size, file, line, func);
> + } else {
> + return sen_realloc_default(ctx, ptr, size, file, line, func);
> + }
> +}
> +
> +char *
> +sen_strdup(sen_ctx *ctx, const char *string, const char* file, int line, const char *func)
> +{
> + if (ctx && ctx->impl && ctx->impl->strdup_func) {
> + return ctx->impl->strdup_func(ctx, string, file, line, func);
> + } else {
> + return sen_strdup_default(ctx, string, file, line, func);
> + }
> +}
> +
> +void *
> +sen_malloc_default(sen_ctx *ctx, size_t size, const char* file, int line, const char *func)
> +{
> void *res = malloc(size);
> if (res) {
> alloc_count++;
> @@ -895,7 +946,7 @@
> }
>
> void *
> -sen_calloc(sen_ctx *ctx, size_t size, const char* file, int line)
> +sen_calloc_default(sen_ctx *ctx, size_t size, const char* file, int line, const char *func)
> {
> void *res = calloc(size, 1);
> if (res) {
> @@ -921,7 +972,7 @@
> }
>
> void *
> -sen_realloc(sen_ctx *ctx, void *ptr, size_t size, const char* file, int line)
> +sen_realloc_default(sen_ctx *ctx, void *ptr, size_t size, const char* file, int line, const char *func)
> {
> void *res;
> if (!size) {
> @@ -953,7 +1004,7 @@
> }
>
> char *
> -sen_strdup(sen_ctx *ctx, const char *s, const char* file, int line)
> +sen_strdup_default(sen_ctx *ctx, const char *s, const char* file, int line, const char *func)
> {
> char *res = strdup(s);
> if (res) {
> @@ -968,7 +1019,7 @@
> }
>
> #ifdef USE_FAIL_MALLOC
> -int
> +static int
> fail_malloc_check(size_t size, const char *file, int line, const char *func)
> {
> if ((sen_fmalloc_file && strcmp(file, sen_fmalloc_file)) ||
> @@ -983,10 +1034,10 @@
> }
>
> void *
> -sen_fail_malloc(sen_ctx *ctx, size_t size, const char* file, int line, const char *func)
> +sen_malloc_fail(sen_ctx *ctx, size_t size, const char* file, int line, const char *func)
> {
> if (fail_malloc_check(size, file, line, func)) {
> - return sen_malloc(ctx, size, file, line);
> + return sen_malloc_default(ctx, size, file, line);
> } else {
> sen_index_expire();
> MERR("fail_malloc (%d) (%s:%d@%s) <%d>", size, file, line, func, alloc_count);
> @@ -995,10 +1046,10 @@
> }
>
> void *
> -sen_fail_calloc(sen_ctx *ctx, size_t size, const char* file, int line, const char *func)
> +sen_calloc_fail(sen_ctx *ctx, size_t size, const char* file, int line, const char *func)
> {
> if (fail_malloc_check(size, file, line, func)) {
> - return sen_calloc(ctx, size, file, line);
> + return sen_calloc_default(ctx, size, file, line);
> } else {
> sen_index_expire();
> MERR("fail_calloc (%d) (%s:%d@%s) <%d>", size, file, line, func, alloc_count);
> @@ -1007,24 +1058,23 @@
> }
>
> void *
> -sen_fail_realloc(sen_ctx *ctx, void *ptr, size_t size, const char* file, int line,
> +sen_realloc_fail(sen_ctx *ctx, void *ptr, size_t size, const char* file, int line,
> const char *func)
> {
> if (fail_malloc_check(size, file, line, func)) {
> - return sen_realloc(ctx, ptr, size, file, line);
> + return sen_realloc_default(ctx, ptr, size, file, line);
> } else {
> sen_index_expire();
> - MERR("fail_realloc (%p,%zu) (%s:%d@%s) <%d>", ptr, size
> - , file, line, func, alloc_count);
> + MERR("fail_realloc (%p,%zu) (%s:%d@%s) <%d>", ptr, size, file, line, func, alloc_count);
> return NULL;
> }
> }
>
> char *
> -sen_fail_strdup(sen_ctx *ctx, const char *s, const char* file, int line, const char *func)
> +sen_strdup_fail(sen_ctx *ctx, const char *s, const char* file, int line, const char *func)
> {
> if (fail_malloc_check(strlen(s), file, line, func)) {
> - return sen_strdup(ctx, s, file, line);
> + return sen_strdup_default(ctx, s, file, line);
> } else {
> sen_index_expire();
> MERR("fail_strdup(%p) (%s:%d@%s) <%d>", s, file, line, func, alloc_count);
> Index: lib/ctx.h
> ===================================================================
> --- lib/ctx.h (リビジョン 1138)
> +++ lib/ctx.h (作業コピー)
> @@ -99,25 +99,14 @@
> #define GMERR(...) ERRSET(&sen_gctx, SEN_ALERT, sen_memory_exhausted, __VA_ARGS__)
> #define GSERR(str) GERR(sen_other_error, "syscall error '%s' (%s)", str, strerror(errno))
>
> -#ifdef USE_FAIL_MALLOC
> -#define SEN_MALLOC(s) sen_fail_malloc(ctx,s,__FILE__,__LINE__,__FUNCTION__)
> -#define SEN_CALLOC(s) sen_fail_calloc(ctx,s,__FILE__,__LINE__,__FUNCTION__)
> -#define SEN_REALLOC(p,s) sen_fail_realloc(ctx,p,s,__FILE__,__LINE__,__FUNCTION__)
> -#define SEN_STRDUP(s) sen_fail_strdup(ctx,s,__FILE__,__LINE__,__FUNCTION__)
> -#define SEN_GMALLOC(s) sen_fail_malloc(&sen_gctx,s,__FILE__,__LINE__,__FUNCTION__)
> -#define SEN_GCALLOC(s) sen_fail_calloc(&sen_gctx,s,__FILE__,__LINE__,__FUNCTION__)
> -#define SEN_GREALLOC(p,s) sen_fail_realloc(&sen_gctx,p,s,__FILE__,__LINE__,__FUNCTION__)
> -#define SEN_GSTRDUP(s) sen_fail_strdup(&sen_gctx,s,__FILE__,__LINE__,__FUNTION__)
> -#else /* USE_FAIL_MALLOC */
> -#define SEN_MALLOC(s) sen_malloc(ctx,s,__FILE__,__LINE__)
> -#define SEN_CALLOC(s) sen_calloc(ctx,s,__FILE__,__LINE__)
> -#define SEN_REALLOC(p,s) sen_realloc(ctx,p,s,__FILE__,__LINE__)
> -#define SEN_STRDUP(s) sen_strdup(ctx,s,__FILE__,__LINE__)
> -#define SEN_GMALLOC(s) sen_malloc(&sen_gctx,s,__FILE__,__LINE__)
> -#define SEN_GCALLOC(s) sen_calloc(&sen_gctx,s,__FILE__,__LINE__)
> -#define SEN_GREALLOC(p,s) sen_realloc(&sen_gctx,p,s,__FILE__,__LINE__)
> -#define SEN_GSTRDUP(s) sen_strdup(&sen_gctx,s,__FILE__,__LINE__)
> -#endif /* USE_FAIL_MALLOC */
> +#define SEN_MALLOC(s) sen_malloc(ctx,s,__FILE__,__LINE__,__FUNCTION__)
> +#define SEN_CALLOC(s) sen_calloc(ctx,s,__FILE__,__LINE__,__FUNCTION__)
> +#define SEN_REALLOC(p,s) sen_realloc(ctx,p,s,__FILE__,__LINE__,__FUNCTION__)
> +#define SEN_STRDUP(s) sen_strdup(ctx,s,__FILE__,__LINE__,__FUNCTION__)
> +#define SEN_GMALLOC(s) sen_malloc(&sen_gctx,s,__FILE__,__LINE__,__FUNCTION__)
> +#define SEN_GCALLOC(s) sen_calloc(&sen_gctx,s,__FILE__,__LINE__,__FUNCTION__)
> +#define SEN_GREALLOC(p,s) sen_realloc(&sen_gctx,p,s,__FILE__,__LINE__,__FUNCTION__)
> +#define SEN_GSTRDUP(s) sen_strdup(&sen_gctx,s,__FILE__,__LINE__,__FUNCTION__)
> #define SEN_FREE(p) sen_free(ctx,p,__FILE__,__LINE__)
> #define SEN_MALLOCN(t,n) ((t *)(SEN_MALLOC(sizeof(t) * (n))))
> #define SEN_GFREE(p) sen_free(&sen_gctx,p,__FILE__,__LINE__)
> @@ -143,17 +132,32 @@
> void sen_ctx_free_lifo(sen_ctx *ctx, void *ptr,
> const char* file, int line, const char *func);
>
> +typedef void *(*sen_malloc_func) (sen_ctx *ctx, size_t size,
> + const char *file, int line, const char *func);
> +typedef void *(*sen_calloc_func) (sen_ctx *ctx, size_t size,
> + const char *file, int line, const char *func);
> +typedef void *(*sen_realloc_func) (sen_ctx *ctx, void *ptr, size_t size,
> + const char *file, int line, const char *func);
> +typedef void *(*sen_strdup_func) (sen_ctx *ctx, const char *string,
> + const char *file, int line, const char *func);
> +
> +void *sen_malloc(sen_ctx *ctx, size_t size, const char* file, int line, const char *func);
> +void *sen_calloc(sen_ctx *ctx, size_t size, const char* file, int line, const char *func);
> +void *sen_realloc(sen_ctx *ctx, void *ptr, size_t size, const char* file, int line, const char *func);
> +char *sen_strdup(sen_ctx *ctx, const char *s, const char* file, int line, const char *func);
> +
> +void *sen_malloc_default(sen_ctx *ctx, size_t size, const char* file, int line, const char *func);
> +void *sen_calloc_default(sen_ctx *ctx, size_t size, const char* file, int line, const char *func);
> +void *sen_realloc_default(sen_ctx *ctx, void *ptr, size_t size, const char* file, int line, const char *func);
> +char *sen_strdup_default(sen_ctx *ctx, const char *s, const char* file, int line, const char *func);
> +
> #ifdef USE_FAIL_MALLOC
> -int fail_malloc_check(size_t size, const char *file, int line, const char *func);
> -void *sen_fail_malloc(sen_ctx *ctx, size_t size, const char* file, int line, const char *func);
> -void *sen_fail_calloc(sen_ctx *ctx, size_t size, const char* file, int line, const char *func);
> -void *sen_fail_realloc(sen_ctx *ctx, void *ptr, size_t size, const char* file, int line, const char *func);
> -char *sen_fail_strdup(sen_ctx *ctx, const char *s, const char* file, int line, const char *func);
> -#endif /* USE_FAIL_MALLOC */
> -void *sen_malloc(sen_ctx *ctx, size_t size, const char* file, int line);
> -void *sen_calloc(sen_ctx *ctx, size_t size, const char* file, int line);
> -void *sen_realloc(sen_ctx *ctx, void *ptr, size_t size, const char* file, int line);
> -char *sen_strdup(sen_ctx *ctx, const char *s, const char* file, int line);
> +void *sen_malloc_fail(sen_ctx *ctx, size_t size, const char* file, int line, const char *func);
> +void *sen_calloc_fail(sen_ctx *ctx, size_t size, const char* file, int line, const char *func);
> +void *sen_realloc_fail(sen_ctx *ctx, void *ptr, size_t size, const char* file, int line, const char *func);
> +char *sen_strdup_fail(sen_ctx *ctx, const char *s, const char* file, int line, const char *func);
> +#endif
> +
> void sen_free(sen_ctx *ctx, void *ptr, const char* file, int line);
>
> void sen_assert(int cond, const char* file, int line, const char* func);
> @@ -327,6 +331,12 @@
> sen_io_mapinfo mi;
> sen_io_mapinfo *segs;
>
> + /* memory allocation portion */
> + sen_malloc_func malloc_func;
> + sen_calloc_func calloc_func;
> + sen_realloc_func realloc_func;
> + sen_strdup_func strdup_func;
> +
> /* ql portion */
> uint32_t ncells;
> uint32_t seqno;
> _______________________________________________
> Senna-dev mailing list
> Senna****@lists*****
> http://lists.sourceforge.jp/mailman/listinfo/senna-dev
> バグ報告方法:http://qwik.jp/senna/bug_report.html
>