[Senna-dev 1036] 動的にメモリ割り当て関数を変更

Back to archive index

Kouhei Sutou kou****@cozmi*****
2008年 9月 25日 (木) 22:36:39 JST


須藤です。

現在はビルド時に--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 メーリングリストの案内
Back to archive index