diff --git a/common/src/tfe_future.cpp b/common/src/tfe_future.cpp index e3e5f3e..e24d785 100644 --- a/common/src/tfe_future.cpp +++ b/common/src/tfe_future.cpp @@ -1,12 +1,26 @@ #include #include #include +#include #include #include +#include + +const char* FP_HISTOGRAM_BINS="10,50,100,500"; + +struct future_promise_instance +{ + int fsid_f_num; + long long f_num; + MESA_htable_handle name_table; + screen_stat_handle_t fs_handle; +}; + struct _future_promise_debug { - struct timeval create_time; + int field_id; + struct timespec create_time; }; struct future { @@ -25,8 +39,43 @@ struct promise promise_ctx_destroy_cb * cb_ctx_destroy; struct _future_promise_debug __debug; }; +static struct future_promise_instance g_FP_instance; +static int g_is_FP_init=0; void future_promise_library_init(void) { + if(g_is_FP_init==1) + { + return; + } + memset(&g_FP_instance,0,sizeof(g_FP_instance)); + MESA_htable_handle htable = MESA_htable_born(); + MESA_htable_set_opt(htable, MHO_SCREEN_PRINT_CTRL, 0); + MESA_htable_set_opt(htable, MHO_THREAD_SAFE, 1); + MESA_htable_set_opt(htable, MHO_MUTEX_NUM, 16); + MESA_htable_set_opt(htable, MHO_HASH_SLOT_SIZE, 1024); + MESA_htable_mature(htable); + g_FP_instance.name_table=htable; + + screen_stat_handle_t fs=NULL; + const char* stat_path="./future.status"; + const char* app_name="FP"; + int value=0; + fs=FS_create_handle(); + FS_set_para(fs, APP_NAME, app_name, strlen(app_name)+1); + value=0; + FS_set_para(fs, FLUSH_BY_DATE, &value, sizeof(value)); + FS_set_para(fs, OUTPUT_DEVICE, stat_path, strlen(stat_path)+1); + value=1; + FS_set_para(fs, PRINT_MODE, &value, sizeof(value)); + value=1; + FS_set_para(fs, CREATE_THREAD, &value, sizeof(value)); + value=2; + FS_set_para(fs, STAT_CYCLE, &value, sizeof(value)); + FS_set_para(fs, HISTOGRAM_GLOBAL_BINS, FP_HISTOGRAM_BINS, strlen(FP_HISTOGRAM_BINS)+1); + g_FP_instance.fsid_f_num=FS_register(fs, FS_STYLE_FIELD, FS_CALC_CURRENT, "futures"); + FS_start(fs); + g_FP_instance.fs_handle=fs; + g_is_FP_init=1; return; } @@ -34,6 +83,27 @@ struct promise * future_to_promise(struct future * f) { return (struct promise *) f; } +struct field_get_set_args +{ + MESA_htable_handle htable; + screen_stat_handle_t fs_handle; +}; +static long field_get_set_cb(void * data, const uchar * key, uint size, void * user_arg) +{ + struct field_get_set_args* args=(struct field_get_set_args*)user_arg; + int field_id=0, ret=0; + if(data==NULL) + { + field_id=FS_register(args->fs_handle, FS_STYLE_HISTOGRAM, FS_CALC_SPEED, (const char * )key); + ret = MESA_htable_add(args->htable, key, size, (void*)field_id); + assert(ret==0); + } + else + { + field_id=(int)data; + } + return field_id; +} struct future * future_create(const char* symbol, future_success_cb * cb_success, future_failed_cb * cb_failed, void * user) { @@ -42,7 +112,14 @@ struct future * future_create(const char* symbol, future_success_cb * cb_success p->f.cb_success = cb_success; p->f.cb_failed = cb_failed; strncpy(p->f.symbol,symbol,sizeof(p->f.symbol)); - gettimeofday(&p->__debug.create_time, NULL); + + clock_gettime(CLOCK_MONOTONIC,&p->__debug.create_time); + void * no_use = NULL; + long cb_ret=0; + struct field_get_set_args args{.htable = g_FP_instance.name_table, .fs_handle = g_FP_instance.fs_handle}; + no_use=MESA_htable_search_cb(g_FP_instance.name_table, symbol, strlen(symbol), field_get_set_cb, &args, &cb_ret); + p->__debug.field_id=(int)cb_ret + FS_operate(g_FP_instance.fs_handle,g_FP_instance.fsid_f_num, 0, FS_OP_ADD, 1); return &p->f; } void future_set_timeout(struct future * f, struct timeval timeout) @@ -54,14 +131,18 @@ void future_set_timeout(struct future * f, struct timeval timeout) } void future_destroy(struct future * f) { - struct promise * promise = future_to_promise(f); - if (promise->cb_ctx_destroy != NULL) + struct promise * p = future_to_promise(f); + if (p->cb_ctx_destroy != NULL) { - promise->cb_ctx_destroy(promise); + p->cb_ctx_destroy(p); } - - memset(promise, 0, sizeof(struct promise)); - free(promise); + struct timespec end; + clock_gettime(CLOCK_MONOTONIC,&end); + long long jiffies=(end->tv_sec-p->__debug.create_time.tv_sec)*1000000000+end->tv_nsec-p->__debug.create_time.tv_nsec; + FS_operate(g_FP_instance.fs_handle, p->__debug.field_id, 0, FS_OP_SET, jiffies); + FS_operate(g_FP_instance.fs_handle,g_FP_instance.fsid_f_num, 0, FS_OP_SUB, 1); + memset(p, 0, sizeof(struct p)); + free(p); } void promise_failed(struct promise * p, enum e_future_error error, const char * what)