diff --git a/Makefile.darwin b/Makefile.darwin index 61df6ec..d6f61eb 100755 --- a/Makefile.darwin +++ b/Makefile.darwin @@ -1,6 +1,6 @@ include config.darwin -OBJS= src/clocks.o src/core_profiler.o src/function_meter.o src/stack.o src/lua50_profiler.o +OBJS= src/clocks.o src/cache.o src/core_profiler.o src/function_meter.o src/stack.o src/lua50_profiler.o profiler: $(OBJS) export MACOSX_DEPLOYMENT_TARGET=10.3 && mkdir -p bin && gcc -bundle -undefined dynamic_lookup -o $(PROFILER_OUTPUT) $(OBJS) diff --git a/Makefile.linux b/Makefile.linux index 0a2c2c9..c57d60f 100755 --- a/Makefile.linux +++ b/Makefile.linux @@ -1,7 +1,6 @@ include config.linux -OBJS= src/clocks.o src/core_profiler.o src/function_meter.o src/stack.o src/lua50_profiler.o - +OBJS= src/clocks.o src/cache.o src/core_profiler.o src/function_meter.o src/stack.o src/lua50_profiler.o profiler: $(OBJS) mkdir -p bin && $(LD) -Bshareable -o $(PROFILER_OUTPUT) $(OBJS) diff --git a/Makefile.win b/Makefile.win index 3304422..41870b1 100755 --- a/Makefile.win +++ b/Makefile.win @@ -5,7 +5,7 @@ V= 2.0.1 include config.win -OBJS= src\clocks.obj src\core_profiler.obj src\function_meter.obj src\stack.obj src\lua50_profiler.obj +OBJS= src\clocks.obj src\cache.obj src\core_profiler.obj src\function_meter.obj src\stack.obj src\lua50_profiler.obj lib: src\$(LIBNAME) diff --git a/src/cache.c b/src/cache.c new file mode 100644 index 0000000..9762694 --- /dev/null +++ b/src/cache.c @@ -0,0 +1,79 @@ +#ifdef __cplusplus +extern "C" { +#endif + +#include "cache.h" +#include +#include + +#define LPROF_CACHE_SIZE (1024*1024) +#define LPROF_LINE_SIZE (256) +#define LPROF_OUTPUT_LINE_SIZE (4096) + +struct Cache +{ + char line_buf[LPROF_LINE_SIZE]; + char data[LPROF_CACHE_SIZE]; + size_t pos; +}; + +static struct Cache* cache; + +void lprofCache_append(FILE* outfile, const char* fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + lprofCache_vappend(outfile, fmt, ap); + va_end(ap); +} + +void lprofCache_vappend(FILE* outfile, const char* fmt, va_list args) +{ + if (cache == NULL) + { + cache = (struct Cache*)malloc(sizeof(struct Cache)); + } + + vsprintf(cache->line_buf, fmt, args); + size_t len = strlen(cache->line_buf); + if (cache->pos + len >= LPROF_CACHE_SIZE - 1) /* leave a space for '\0' */ + { + lprofCache_write_all(outfile); + } + + memcpy(cache->data + cache->pos, cache->line_buf, len + 1); /* len+1 copy '\0' */ + cache->pos += len; +} + +void lprofCache_write_all(FILE* outfile) +{ + size_t start = 0; + while(cache->pos > 0) + { + size_t line_size = cache->pos < LPROF_OUTPUT_LINE_SIZE ? + cache->pos : LPROF_OUTPUT_LINE_SIZE; + fwrite(cache->data + start, sizeof(char), line_size, outfile); + cache->pos -= line_size; + start += line_size; + } +} + +/* test cache */ +/* +int main(int argc, char const *argv[]) +{ + FILE* file = fopen("/tmp/test.out", "a"); + lprofCache_append(file, "abcdefg"); + lprofCache_append(file, "b\n"); + lprofCache_append(file, "c\n"); + + lprofCache_write_all(file); + fclose(file); + + return 0; +} +*/ + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/src/cache.h b/src/cache.h new file mode 100644 index 0000000..d2ad295 --- /dev/null +++ b/src/cache.h @@ -0,0 +1,30 @@ +/* +** LuaProfiler +** Jennal +** 2014-11-15 +*/ + +/***************************************************************************** +cache.h: + Module to faster write file + +Design: + 'lprofCache_append()' append string to cache + 'lprofCache_vappend()' append string to cache with va_list + 'lprofCache_write_all()' write all cache data to output and clear cache +*****************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +void lprofCache_append(FILE* outfile, const char* fmt, ...); +void lprofCache_vappend(FILE* outfile, const char* fmt, va_list args); +void lprofCache_write_all(FILE* outfile); + +#ifdef __cplusplus +} +#endif diff --git a/src/clocks.c b/src/clocks.c index 132e1c8..db8837d 100755 --- a/src/clocks.c +++ b/src/clocks.c @@ -14,6 +14,11 @@ clocks.c: was started *****************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + + #include #include "clocks.h" @@ -61,3 +66,6 @@ clock_t clocks; return (float)clocks / (float)CLOCKS_PER_SEC; } +#ifdef __cplusplus +} +#endif diff --git a/src/clocks.h b/src/clocks.h index a230e2a..f5c695a 100755 --- a/src/clocks.h +++ b/src/clocks.h @@ -14,7 +14,16 @@ clocks.h: was started *****************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + + #include void lprofC_start_timer(clock_t *time_marker); float lprofC_get_seconds(clock_t time_marker); + +#ifdef __cplusplus +} +#endif diff --git a/src/core_profiler.c b/src/core_profiler.c index c879b9c..c8f30da 100755 --- a/src/core_profiler.c +++ b/src/core_profiler.c @@ -34,14 +34,19 @@ the vertex is "printed" only after all his descendents have been processed (in a depth-first search recursive algorithm). *****************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + + #include #include #include #include #include "function_meter.h" - #include "core_profiler.h" +#include "cache.h" /* Jennal added */ /* default log name (%s is used to place a random string) */ #define OUT_FILENAME "lprof_%s.out" @@ -57,13 +62,19 @@ static float function_call_time; /* output a line to the log file, using 'printf()' syntax */ /* assume the timer is off */ static void output(const char *format, ...) { + /* Jennal modified */ + // va_list ap; + // va_start(ap, format); + // vfprintf(outf, format, ap); + // va_end(ap); + + // /* write now to avoid delays when the timer is on */ + // fflush(outf); + va_list ap; va_start(ap, format); - vfprintf(outf, format, ap); + lprofCache_vappend(outf, format, ap); va_end(ap); - - /* write now to avoid delays when the timer is on */ - fflush(outf); } @@ -97,10 +108,18 @@ int lprofP_callhookOUT(lprofP_STATE* S) { S->stack_level--; - /* 0: do not resume the parent function's timer yet... */ - info = lprofM_leave_function(S, 0); + //Jennal move up + /* original code is + // 0: do not resume the parent function's timer yet... + info = lprofM_leave_function(S, 0); + // writing a log may take too long to be computed with the function's time ... + lprofM_pause_total_time(S); + */ /* writing a log may take too long to be computed with the function's time ...*/ lprofM_pause_total_time(S); + /* 0: do not resume the parent function's timer yet... */ + info = lprofM_leave_function(S, 0); + info->local_time += function_call_time; info->total_time += function_call_time; @@ -169,6 +188,7 @@ lprofP_STATE* lprofP_init_core_profiler(const char *_out_filename, int isto_prin /* initialize the 'function_meter' */ S = lprofM_init(); if(!S) { + lprofCache_write_all(outf); fclose(outf); return 0; } @@ -177,7 +197,11 @@ lprofP_STATE* lprofP_init_core_profiler(const char *_out_filename, int isto_prin } void lprofP_close_core_profiler(lprofP_STATE* S) { - if(outf) fclose(outf); + if(outf) { + lprofCache_write_all(outf); + fclose(outf); + } + if(S) free(S); } @@ -195,3 +219,6 @@ lprofP_STATE* lprofP_create_profiler(float _function_call_time) { return S; } +#ifdef __cplusplus +} +#endif diff --git a/src/core_profiler.h b/src/core_profiler.h index 447ec88..e63e40f 100755 --- a/src/core_profiler.h +++ b/src/core_profiler.h @@ -16,6 +16,10 @@ Design (using the Lua callhook mechanism) : 'lprofP_callhookOUT' called whenever Lua leaves a function *****************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + #include "stack.h" /* computes new stack and new timer */ @@ -25,7 +29,11 @@ void lprofP_callhookIN(lprofP_STATE* S, char *func_name, char *file, int linedef /* returns if there is another function in the stack */ int lprofP_callhookOUT(lprofP_STATE* S); +void lprofP_close_core_profiler(lprofP_STATE* S); /* opens the log file */ /* returns true if the file could be opened */ lprofP_STATE* lprofP_init_core_profiler(const char *_out_filename, int isto_printheader, float _function_call_time); +#ifdef __cplusplus +} +#endif diff --git a/src/function_meter.c b/src/function_meter.c index 709846f..7c7404e 100755 --- a/src/function_meter.c +++ b/src/function_meter.c @@ -25,6 +25,11 @@ function_meter.c: another one or when the function terminates *****************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + + #include #include #include @@ -201,3 +206,8 @@ lprofP_STATE* lprofM_init() { return S; } else return NULL; } + + +#ifdef __cplusplus +} +#endif diff --git a/src/function_meter.h b/src/function_meter.h index 39afd3a..7445de3 100755 --- a/src/function_meter.h +++ b/src/function_meter.h @@ -25,6 +25,14 @@ function_meter.c: another one or when the function terminates *****************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + + + + #include "stack.h" @@ -62,3 +70,7 @@ lprofS_STACK_RECORD *lprofM_leave_function(lprofP_STATE* S, int isto_resume); /* init stack */ lprofP_STATE* lprofM_init(); + +#ifdef __cplusplus +} +#endif diff --git a/src/lua50_profiler.c b/src/lua50_profiler.c index 4e64db1..92e8562 100755 --- a/src/lua50_profiler.c +++ b/src/lua50_profiler.c @@ -9,6 +9,7 @@ lua50_profiler.c: Lua version dependent profiler interface *****************************************************************************/ +#include "lua50_profiler.h" #include #include #include @@ -17,9 +18,14 @@ lua50_profiler.c: #include "core_profiler.h" #include "function_meter.h" -#include "lua.h" #include "lauxlib.h" +#ifdef __cplusplus +extern "C" { +#endif + + + /* Indices for the main profiler stack and for the original exit function */ static int exit_id; static int profstate_id; @@ -36,6 +42,7 @@ static void callhook(lua_State *L, lua_Debug *ar) { lua_pushlightuserdata(L, &profstate_id); lua_gettable(L, LUA_REGISTRYINDEX); S = (lprofP_STATE*)lua_touserdata(L, -1); + lua_pop(L, 1); if (lua_getstack(L, 1, &previous_ar) == 0) { currentline = -1; @@ -238,3 +245,6 @@ int luaopen_profiler(lua_State *L) { lua_settable (L, -3); return 1; } +#ifdef __cplusplus +} +#endif diff --git a/src/lua50_profiler.h b/src/lua50_profiler.h new file mode 100644 index 0000000..a58e895 --- /dev/null +++ b/src/lua50_profiler.h @@ -0,0 +1,25 @@ +/* + * lua50_profiler.h + * RDTower + * + * Created by changshuai on 14/11/10. + * + */ + +#ifndef RDTower_lua50_profiler_h +#define RDTower_lua50_profiler_h + + +#ifdef __cplusplus +extern "C" { +#endif + +#include "lua.h" + +int luaopen_profiler(lua_State *L); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/luaprofiler.h b/src/luaprofiler.h index e435610..c9bd62c 100755 --- a/src/luaprofiler.h +++ b/src/luaprofiler.h @@ -8,7 +8,15 @@ luaprofiler.h: Must be included by your main module, in order to profile Lua programs *****************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + + void init_profiler(void *); + +#ifdef __cplusplus +} +#endif -void init_profiler(void *); diff --git a/src/stack.c b/src/stack.c index eff6198..20e9937 100755 --- a/src/stack.c +++ b/src/stack.c @@ -9,6 +9,13 @@ stack.c: Simple stack manipulation *****************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + + + + #include #include #include "stack.h" @@ -31,3 +38,6 @@ lprofS_STACK q; free(q); return r; } +#ifdef __cplusplus +} +#endif diff --git a/src/stack.h b/src/stack.h index b513f92..423c3cc 100755 --- a/src/stack.h +++ b/src/stack.h @@ -12,6 +12,11 @@ stack.h: #ifndef _STACK_H #define _STACK_H +#ifdef __cplusplus +extern "C" { +#endif + + #include typedef struct lprofS_sSTACK_RECORD lprofS_STACK_RECORD; @@ -42,3 +47,7 @@ void lprofS_push(lprofS_STACK *p, lprofS_STACK_RECORD r); lprofS_STACK_RECORD lprofS_pop(lprofS_STACK *p); #endif + +#ifdef __cplusplus +} +#endif