summaryrefslogtreecommitdiff
path: root/support
diff options
context:
space:
mode:
authorQiuwen Lu <[email protected]>2016-09-09 13:48:47 +0800
committerQiuwen Lu <[email protected]>2016-09-09 13:48:47 +0800
commit3944b405b62b2c20476716dcbcd5cd0fe1b01c18 (patch)
treeb3388e31cb04990d357a1b656b9865b0d3db85cb /support
parent2dad3145217a5bbfdc62940a464f2ae6f8015333 (diff)
集成MESA_fs2
Diffstat (limited to 'support')
-rw-r--r--support/CMakeLists.txt3
-rw-r--r--support/MESA_fs2/.gitignore6
-rw-r--r--support/MESA_fs2/CMakeLists.txt2
-rw-r--r--support/MESA_fs2/readme.txt1
-rw-r--r--support/MESA_fs2/src/MESA_field_stat.cc698
-rw-r--r--support/MESA_fs2/src/field_stat2.h65
6 files changed, 774 insertions, 1 deletions
diff --git a/support/CMakeLists.txt b/support/CMakeLists.txt
index 394a7f8..874b489 100644
--- a/support/CMakeLists.txt
+++ b/support/CMakeLists.txt
@@ -1,2 +1,3 @@
cmake_minimum_required(VERSION 2.6)
-add_subdirectory(MESA_prof_load) \ No newline at end of file
+add_subdirectory(MESA_prof_load)
+add_subdirectory(MESA_fs2) \ No newline at end of file
diff --git a/support/MESA_fs2/.gitignore b/support/MESA_fs2/.gitignore
new file mode 100644
index 0000000..3e978b5
--- /dev/null
+++ b/support/MESA_fs2/.gitignore
@@ -0,0 +1,6 @@
+SI/
+*.log
+*.o
+*.so
+bin/avrule/
+bin/avlog/
diff --git a/support/MESA_fs2/CMakeLists.txt b/support/MESA_fs2/CMakeLists.txt
new file mode 100644
index 0000000..e0591a2
--- /dev/null
+++ b/support/MESA_fs2/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_library(MESA_fs2 src/MESA_field_stat.cc)
+target_include_directories(MESA_fs2 INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/src/") \ No newline at end of file
diff --git a/support/MESA_fs2/readme.txt b/support/MESA_fs2/readme.txt
new file mode 100644
index 0000000..cf84865
--- /dev/null
+++ b/support/MESA_fs2/readme.txt
@@ -0,0 +1 @@
+See maat_stat.cpp in MAAT project for more guidance. \ No newline at end of file
diff --git a/support/MESA_fs2/src/MESA_field_stat.cc b/support/MESA_fs2/src/MESA_field_stat.cc
new file mode 100644
index 0000000..26c5450
--- /dev/null
+++ b/support/MESA_fs2/src/MESA_field_stat.cc
@@ -0,0 +1,698 @@
+#include "field_stat2.h"
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <assert.h>
+#include <sys/time.h>
+
+#define INIT_STAT_FIELD_NUM 64
+#define MAX_STAT_COLUMN_NUM 32
+
+#define STATUS_PER_LINE 6
+#define FIELD_PER_LINE 8
+int FIELD_STAT_VERSION_2_20160509=0;
+
+#if(__GNUC__ * 100 + __GNUC_MINOR__ * 10 + __GNUC_PATCHLEVEL__ >= 410)
+#define atomic_inc(x) __sync_add_and_fetch((x),1)
+#define atomic_dec(x) __sync_sub_and_fetch((x),1)
+#define atomic_add(x,y) __sync_add_and_fetch((x),(y))
+#define atomic_sub(x,y) __sync_sub_and_fetch((x),(y))
+typedef long atomic_t;
+#define ATOMIC_INIT(i) { (i) }
+#define atomic_read(x) __sync_add_and_fetch((x),0)
+#define atomic_set(x,y) __sync_lock_test_and_set((x),y)
+#else
+typedef long atomic_t;
+#define atomic_inc(x) ((*(x))++)
+#define atomic_dec(x) ((*(x))--)
+#define atomic_add(x,y) ((*(x))+=(y))
+#define atomic_sub(x,y) ((*(x))-=(y))
+#define ATOMIC_INIT(i) { (i) }
+#define atomic_read(x) (*(x))
+#define atomic_set(x,y) ((*(x))=(y))
+#endif
+const char* draw_line="________________________________________________________________________________________________________________________________________________";
+const char* draw_boundary="============================================================";
+struct stat_field_t
+{
+ char *filed_name;
+ long long current_value;
+ long long last_output_value;
+};
+
+struct display_manifest_t
+{
+ char* name;
+ int is_invisible;
+ int idx;
+ int is_ratio;
+ int numerator_id;
+ int denominator_id;
+ int output_scaling; //negative value: zoom in; positive value: zoom out;
+ enum field_dsp_style_t style;
+ enum field_calc_algo calc_type;
+};
+struct stat_unit_t
+{
+ long long current_value;
+ long long last_output_value;
+ long long last_diff;
+};
+
+struct FS_space_t
+{
+ int stat_cycle;
+ int screen_print_trigger;
+ int print_mode; //1:Rewrite ,2: Append
+ int create_thread;
+ int running;
+
+ int line_cnt;
+ int display_cnt;
+ int single_cnt;//including line_cnt;
+ int matrix_base;
+ int column_cnt;
+ int cloumn_id[MAX_STAT_COLUMN_NUM];
+ int display_size;
+ struct display_manifest_t *display;
+
+ struct stat_unit_t* stat_array;//for styple STATUS/FIELD
+ char* output_file;
+ FILE* fp;
+ struct timespec last_display_time;
+};
+
+void *thread_screen_print(void *arg);
+
+screen_stat_handle_t FS_create_handle(void)
+{
+ struct FS_space_t* handle=(struct FS_space_t*)calloc(sizeof(struct FS_space_t),1);
+ handle->screen_print_trigger=1;
+ handle->print_mode=1;
+ handle->stat_cycle=2;
+ handle->create_thread=1;
+ handle->display_size=INIT_STAT_FIELD_NUM;
+ handle->running=0;
+ handle->display=(struct display_manifest_t *)calloc(sizeof(struct display_manifest_t ),handle->display_size);
+ return handle;
+}
+int FS_set_para(screen_stat_handle_t handle, enum FS_option type,const void* value,int size)
+{
+ struct FS_space_t* _handle=(struct FS_space_t*)handle;
+ FILE* fp=NULL;
+ int int_val=0;
+ if(_handle->running==1)
+ {
+ return -1;
+ }
+ if(type!=OUTPUT_DEVICE)
+ {
+ int_val=*(const int*)value;
+ }
+ switch(type)
+ {
+ case OUTPUT_DEVICE:
+ fp=fopen((const char*)value,"w");
+ if(fp==NULL)
+ {
+ printf("Field Stat: open %s failed.\n",(const char*)value);
+ return -1;
+ }
+ _handle->fp=fp;
+ _handle->output_file=(char*)calloc(sizeof(char),size);
+ memcpy(_handle->output_file,value,size);
+ fp=NULL;
+ break;
+ case PRINT_MODE:
+ if(size!=4||(int_val!=1&&int_val!=2))
+ {
+ return -1;
+ }
+ _handle->print_mode=int_val;
+ break;
+ case STAT_CYCLE:
+ if(size!=4||(int_val==0))
+ {
+ return -1;
+ }
+ _handle->stat_cycle=int_val;
+ break;
+ case PRINT_TRIGGER:
+ if(size!=4||(int_val!=0&&int_val!=1))
+ {
+ return -1;
+ }
+ _handle->screen_print_trigger=int_val;
+ break;
+ case CREATE_THREAD:
+ if(size!=4||(int_val!=0&&int_val!=1))
+ {
+ return -1;
+ }
+ _handle->create_thread=int_val;
+ break;
+ case ID_INVISBLE:
+ if(int_val<0||int_val>=_handle->display_cnt)
+ {
+ return -1;
+ }
+ _handle->display[int_val].is_invisible=1;
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+}
+void FS_start(screen_stat_handle_t handle)
+{
+ struct FS_space_t* _handle=(struct FS_space_t*)handle;
+ pthread_t cfg_mon_t;
+ int i=0,j=0,pos=0;
+ int stat_unit_cnt=0;
+ stat_unit_cnt=_handle->single_cnt+_handle->line_cnt*_handle->column_cnt;
+ for(i=0;i<_handle->display_cnt;i++)
+ {
+ switch(_handle->display[i].style)
+ {
+ case FS_STYLE_FIELD:
+ case FS_STYLE_STATUS:
+ _handle->display[i].idx=pos;
+ pos++;
+ break;
+ case FS_STYLE_COLUMN:
+ _handle->display[i].idx=j;
+ _handle->cloumn_id[j]=i;
+ j++;
+ break;
+ case FS_STYLE_LINE:
+ _handle->display[i].idx=pos;
+ pos+=_handle->column_cnt;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ }
+ assert(j==_handle->column_cnt);
+ _handle->stat_array=(struct stat_unit_t*)calloc(sizeof(struct stat_unit_t),stat_unit_cnt);
+ _handle->running=1;
+ clock_gettime(CLOCK_MONOTONIC,&(_handle->last_display_time));
+ if(_handle->create_thread==1)
+ {
+ pthread_create(&cfg_mon_t, NULL, thread_screen_print, (void*)handle);
+ }
+ return;
+}
+void FS_stop(screen_stat_handle_t* handle)
+{
+ int i=0;
+ struct FS_space_t* _handle=*(struct FS_space_t**)handle;
+ _handle->create_thread=0;
+ for(i=0;i<_handle->display_cnt;i++)
+ {
+ free(_handle->display[i].name);
+ _handle->display[i].name=NULL;
+ }
+ free(_handle->display);
+ free(_handle->stat_array);
+ _handle->stat_array=NULL;
+ free(_handle->output_file);
+ _handle->output_file=NULL;
+ free(_handle);
+ if(strlen(_handle->output_file)>0)
+ {
+ fclose(_handle->fp);
+ _handle->fp=NULL;
+ }
+ *handle=NULL;
+ return;
+}
+int FS_register(screen_stat_handle_t handle,enum field_dsp_style_t style,enum field_calc_algo calc_type,const char* name)
+{
+ struct FS_space_t* _handle=(struct FS_space_t*)handle;
+ struct display_manifest_t * choosen=NULL;
+ int id=0;
+ if(_handle->running==1)
+ {
+ return -1;
+ }
+ switch(style)
+ {
+ case FS_STYLE_FIELD:
+ case FS_STYLE_STATUS:
+ _handle->single_cnt++;
+ break;
+ case FS_STYLE_LINE:
+ _handle->line_cnt++;
+ break;
+ case FS_STYLE_COLUMN:
+ _handle->column_cnt++;
+ break;
+ default:
+ return -1;
+ }
+ id=_handle->display_cnt;
+ _handle->display_cnt++;
+ if(_handle->display_cnt==_handle->display_size)
+ {
+ _handle->display_size+=INIT_STAT_FIELD_NUM;
+ _handle->display=(struct display_manifest_t *)realloc(_handle->display,sizeof(struct display_manifest_t )*_handle->display_size);
+ }
+ choosen=&(_handle->display[id]);
+ choosen->calc_type=calc_type;
+ choosen->style=style;
+ choosen->is_ratio=0;
+ choosen->output_scaling=1;
+ choosen->name=(char*)calloc(sizeof(char),strlen(name)+1);
+ memcpy(choosen->name,name,strlen(name));
+ return id;
+}
+int FS_register_ratio(screen_stat_handle_t handle,int numerator_id,int denominator_id,int scaling,enum field_dsp_style_t style,enum field_calc_algo calc_type,const char* name)
+{
+ struct FS_space_t* _handle=(struct FS_space_t*)handle;
+ struct display_manifest_t * choosen=NULL;
+ int id=0;
+ if(_handle->running==1)
+ {
+ return -1;
+ }
+ if(numerator_id>=_handle->display_cnt||denominator_id>=_handle->display_cnt)
+ {
+ return -1;
+ }
+ if(_handle->display[denominator_id].is_ratio==1||_handle->display[numerator_id].is_ratio==1)
+ {
+ return -1;
+ }
+ if(_handle->display[denominator_id].style==FS_STYLE_LINE||_handle->display[numerator_id].style==FS_STYLE_LINE)
+ {
+ return -1;
+ }
+ if(style==FS_STYLE_LINE)
+ {
+ return -1;
+ }
+ if(scaling==0)
+ {
+ return -1;
+ }
+ switch(style)
+ {
+ case FS_STYLE_FIELD:
+ case FS_STYLE_STATUS:
+ _handle->single_cnt++;
+ break;
+ case FS_STYLE_LINE:
+ _handle->line_cnt++;
+ break;
+ case FS_STYLE_COLUMN:
+ _handle->column_cnt++;
+ break;
+ default:
+ return -1;
+ }
+ id=_handle->display_cnt;
+ _handle->display_cnt++;
+ if(_handle->display_cnt==_handle->display_size)
+ {
+ _handle->display_size+=INIT_STAT_FIELD_NUM;
+ _handle->display=(struct display_manifest_t *)realloc(_handle->display,sizeof(struct display_manifest_t )*_handle->display_size);
+ }
+ choosen=&(_handle->display[id]);
+ choosen->calc_type=calc_type;
+ choosen->style=style;
+ choosen->is_ratio=1;
+ choosen->output_scaling=scaling;
+ choosen->denominator_id=denominator_id;
+ choosen->numerator_id=numerator_id;
+ choosen->name=(char*)calloc(sizeof(char),strlen(name)+1);
+ memcpy(choosen->name,name,strlen(name));
+ return id;
+}
+int FS_operate(screen_stat_handle_t handle,int id,int column_id,enum field_op op,long long value)
+{
+ struct FS_space_t* _handle=(struct FS_space_t*)handle;
+ int i=0,j=0;
+ struct stat_unit_t* target;
+ if(id>=_handle->display_cnt)
+ {
+ return -1;
+ }
+ if(_handle->display[id].style==FS_STYLE_LINE)
+ {
+ if(column_id>=_handle->display_cnt||column_id>=_handle->display_cnt||_handle->display[column_id].style!=FS_STYLE_COLUMN)
+ {
+ return -1;
+ }
+ i=_handle->display[id].idx;
+ j=_handle->display[column_id].idx;
+ target=&(_handle->stat_array[i+j]);
+ }
+ else
+ {
+ i=_handle->display[id].idx;
+ target=&(_handle->stat_array[i]);
+ }
+ switch(op)
+ {
+ case FS_OP_ADD:
+ atomic_add(&(target->current_value),value);
+ break;
+ case FS_OP_SET:
+ atomic_set(&(target->current_value),value);
+ break;
+ default:
+ return -1;
+ break;
+ }
+ return 0;
+}
+static long long get_stat_unit_val(struct FS_space_t* _handle,int id,int column_id,enum field_calc_algo calc_type,int is_refer)
+{
+ display_manifest_t* p=NULL;
+ stat_unit_t* target=NULL;
+ p=&(_handle->display[id]);
+ long long value=0;
+ switch(p->style)
+ {
+ case FS_STYLE_FIELD:
+ case FS_STYLE_STATUS:
+ target=&(_handle->stat_array[p->idx]);
+ break;
+ case FS_STYLE_LINE:
+ target=&(_handle->stat_array[p->idx+_handle->display[column_id].idx]);
+ break;
+ case FS_STYLE_COLUMN:
+ default:
+ assert(0);
+ break;
+ }
+ value= atomic_read(&(target->current_value));
+ if(is_refer==0)
+ {
+ target->last_diff=value-target->last_output_value;
+ target->last_output_value=value;
+ }
+ switch(calc_type)
+ {
+ case FS_CALC_CURRENT:
+ break;
+ case FS_CALC_SPEED:
+ value=target->last_diff;
+ break;
+ default:
+ assert(0);
+ }
+
+ return value;
+}
+static double get_stat_ratio(struct FS_space_t* _handle,int numerator_id,int denominator_id,int scaling,int line_id,enum field_calc_algo calc_type)
+{
+ long long value_n=0,value_d=0;
+ double ratio=0.0;
+
+ if(_handle->display[numerator_id].style==FS_STYLE_COLUMN)
+ {
+ assert(_handle->display[denominator_id].style==FS_STYLE_COLUMN);
+ value_n=get_stat_unit_val(_handle,line_id,numerator_id,calc_type,1);
+ value_d=get_stat_unit_val(_handle,line_id,denominator_id,calc_type,1);
+ }
+ else
+ {
+ value_n=get_stat_unit_val(_handle,numerator_id,0,calc_type,1);
+ value_d=get_stat_unit_val(_handle,denominator_id,0,calc_type,1);
+ }
+ if(value_d==0)
+ {
+ ratio=0.0;
+ }
+ else
+ {
+ if(scaling>0)
+ {
+ ratio=((double)value_n*scaling/value_d);
+ }
+ else
+ {
+ ratio=((double)value_n/(value_d*scaling*-1));
+ }
+ }
+ return ratio;
+}
+static int output_style_status(struct FS_space_t* _handle,long long interval_ms,char*print_buf, unsigned int size)
+{
+ int i=0,j=0;
+ display_manifest_t* p=NULL;
+ long long value=0;
+ double ratio=0.0;
+ char* pos=print_buf;
+
+ for(i=0;i<_handle->display_cnt;i++)
+ {
+ p=&(_handle->display[i]);
+ if(p->style!=FS_STYLE_STATUS)
+ {
+ continue;
+ }
+ if(p->is_invisible==1)
+ {
+ value=get_stat_unit_val(_handle,i, 0, p->calc_type, 0);
+ continue;
+ }
+ if(p->is_ratio==1)
+ {
+ ratio=get_stat_ratio(_handle,p->numerator_id,p->denominator_id,p->output_scaling, 0,p->calc_type);
+ pos+=snprintf(pos,size-(pos-print_buf),"%s: %10.2e\t",p->name,ratio);
+ }
+ else
+ {
+ value=get_stat_unit_val(_handle,i, 0, p->calc_type, 0);
+ if(p->calc_type==FS_CALC_SPEED)
+ {
+ value=value*p->output_scaling*1000/interval_ms;
+ }
+ pos+=snprintf(pos,size-(pos-print_buf),"%s: %-10lld\t",p->name,value);
+ }
+ j++;
+ if(j==STATUS_PER_LINE)
+ {
+ pos+=snprintf(pos,sizeof(print_buf)-(pos-print_buf),"\n");
+ j=0;
+ }
+ }
+ if(pos-print_buf>0)
+ {
+ if(*(pos-1)=='\n')
+ {
+ pos--;
+ }
+ pos+=snprintf(pos,sizeof(print_buf)-(pos-print_buf),"\n%s\n",draw_line);
+ }
+ return pos-print_buf;
+}
+static int output_style_field(struct FS_space_t* _handle,long long interval_ms,char*print_buf, unsigned int size)
+{
+ int i=0,j=0;
+ display_manifest_t* p=NULL;
+ long long value=0;
+ double ratio=0.0;
+ char* pos=print_buf;
+ int field_id[INIT_STAT_FIELD_NUM]={0};
+ int field_cnt=0;
+
+ for(i=0;i<_handle->display_cnt;i++)
+ {
+ p=&(_handle->display[i]);
+ if(p->style!=FS_STYLE_FIELD)
+ {
+ continue;
+ }
+ if(p->is_invisible==1)
+ {
+ //for update last_output
+ get_stat_unit_val( _handle, field_id[i+j], 0,FS_CALC_CURRENT, 0);
+ continue;
+ }
+ field_id[field_cnt]=i;
+ field_cnt++;
+ }
+ for(i=0;i<field_cnt;i++)
+ {
+ pos+=snprintf(pos,size-(pos-print_buf),"\t");
+ for(j=0;j<FIELD_PER_LINE&&i+j<field_cnt;j++)
+ {
+ p=&(_handle->display[field_id[i+j]]);
+ pos+=snprintf(pos,size-(pos-print_buf),"%10s\t",p->name);
+ }
+ pos+=snprintf(pos,size-(pos-print_buf),"\nsum\t");
+ for(j=0;j<FIELD_PER_LINE&&i+j<field_cnt;j++)
+ {
+ p=&(_handle->display[field_id[i+j]]);
+ if(p->is_ratio==1)
+ {
+ ratio=get_stat_ratio(_handle,p->numerator_id,p->denominator_id,p->output_scaling, 0,FS_CALC_CURRENT);
+ pos+=snprintf(pos,size-(pos-print_buf),"%f\t",ratio);
+ }
+ else
+ {
+ value=get_stat_unit_val( _handle, field_id[i+j], 0,FS_CALC_CURRENT, 0);
+ pos+=snprintf(pos,sizeof(print_buf)-(pos-print_buf),"%10lld\t",value);
+ }
+ }
+ pos+=snprintf(pos,sizeof(print_buf)-(pos-print_buf),"\nspeed/s\t");
+ for(j=0;j<FIELD_PER_LINE&&i+j<field_cnt;j++)
+ {
+ if(p->is_ratio==1)
+ {
+ ratio=get_stat_ratio(_handle,p->numerator_id,p->denominator_id,p->output_scaling, 0,FS_CALC_SPEED);
+ pos+=snprintf(pos,size-(pos-print_buf),"%10.2e\t",ratio);
+ }
+ else
+ {
+ value=get_stat_unit_val( _handle, field_id[i+j], 0,FS_CALC_SPEED, 1);
+ pos+=snprintf(pos,size-(pos-print_buf),"%10lld\t",value*1000/interval_ms);
+ }
+ }
+ i+=j;
+ pos+=snprintf(pos,sizeof(print_buf)-(pos-print_buf),"\n");
+ }
+ if(pos-print_buf>0)
+ {
+ if(*(pos-1)=='\n')
+ {
+ pos--;
+ }
+ pos+=snprintf(pos,sizeof(print_buf)-(pos-print_buf),"\n%s\n",draw_line);
+ }
+ return pos-print_buf;
+}
+static int output_style_table(struct FS_space_t* _handle,long long interval_ms,char*print_buf, unsigned int size)
+{
+ int i=0,j=0;
+ char* pos=print_buf;
+ display_manifest_t* p_column=NULL,*p_line=NULL;
+ double ratio=0.0,speed=0.0;
+ long long value=0;
+ for(i=0;i<_handle->column_cnt;i++)
+ {
+ if(i==0)
+ {
+ pos+=snprintf(pos,size-(pos-print_buf),"\t\t");
+ }
+ p_column=&(_handle->display[_handle->cloumn_id[i]]);
+ if(p_column->is_invisible==1)
+ {
+ continue;
+ }
+ pos+=snprintf(pos,size-(pos-print_buf),"\t%10s",p_column->name);
+ }
+ pos+=snprintf(pos,sizeof(print_buf)-(pos-print_buf),"\n");
+ for(i=0;i<_handle->display_cnt;i++)
+ {
+ p_line=&(_handle->display[i]);
+ if(p_line->style!=FS_STYLE_LINE)
+ {
+ continue;
+ }
+ pos+=snprintf(pos,size-(pos-print_buf),"%-20s\t",p_line->name);
+ for(j=0;j<_handle->column_cnt;j++)
+ {
+ p_column=&(_handle->display[_handle->cloumn_id[j]]);
+ if(p_column->is_invisible==1)
+ {
+ //for flush last_output_value
+ get_stat_unit_val( _handle, i, _handle->cloumn_id[j],p_column->calc_type, 0);
+ continue;
+ }
+ if(p_column->is_ratio==1)
+ {
+ ratio=get_stat_ratio(_handle,p_column->numerator_id,p_column->denominator_id,p_column->output_scaling, i,p_column->calc_type);
+ pos+=snprintf(pos,size-(pos-print_buf),"%10.2e\t",ratio);
+ }
+ else
+ {
+ value=get_stat_unit_val(_handle,i, _handle->cloumn_id[j], p_column->calc_type, 0);
+ if(p_column->calc_type==FS_CALC_SPEED)
+ {
+ speed=(double)value*1000/interval_ms;
+ pos+=snprintf(pos,size-(pos-print_buf),"%10.2e\t",speed);
+
+ }
+ else
+ {
+ pos+=snprintf(pos,size-(pos-print_buf),"%10lld\t",value);
+ }
+ }
+ }
+ pos+=snprintf(pos,sizeof(print_buf)-(pos-print_buf),"\n");
+
+ }
+ if(pos-print_buf>0)
+ {
+ if(*(pos-1)=='\n')
+ {
+ pos--;
+ }
+ pos+=snprintf(pos,sizeof(print_buf)-(pos-print_buf),"\n");
+ }
+ return pos-print_buf;
+}
+void FS_passive_output(screen_stat_handle_t handle)
+{
+ struct FS_space_t* _handle=(struct FS_space_t*)handle;
+ struct timespec now;
+ time_t current=0;
+ char print_buf[1024*64]={0};
+ char*pos=NULL;
+ time(&current);
+ if(_handle->running==0)
+ {
+ return;
+ }
+ if(_handle->screen_print_trigger==0)
+ {
+ return;
+ }
+ clock_gettime(CLOCK_MONOTONIC,&now);
+ long long interval_ms=(now.tv_sec-_handle->last_display_time.tv_sec)*1000+(now.tv_nsec-_handle->last_display_time.tv_nsec)/1000000;
+ if(interval_ms<1)
+ {
+ return;
+ }
+ pos=print_buf;
+ pos+=snprintf(pos,sizeof(print_buf)-(pos-print_buf),"%s%s",draw_boundary,ctime(&current));
+ pos--;//jump '\n' generate by ctime()
+ pos+=snprintf(pos,sizeof(print_buf)-(pos-print_buf),"%s\n",draw_boundary);
+
+ pos+=output_style_status(_handle, interval_ms,pos, sizeof(print_buf)-(pos-print_buf));
+ pos+=output_style_field(_handle, interval_ms,pos, sizeof(print_buf)-(pos-print_buf));
+ pos+=output_style_table(_handle, interval_ms,pos, sizeof(print_buf)-(pos-print_buf));
+
+ if(_handle->fp==NULL)
+ {
+ printf("Field Stat: open %s failed.\n",_handle->output_file);
+ return;
+ }
+ if(_handle->print_mode==1)
+ {
+ fseek(_handle->fp,0,SEEK_SET);
+ }
+ fwrite(print_buf,pos-print_buf,1,_handle->fp);
+ fflush(_handle->fp);
+ memcpy(&(_handle->last_display_time),&now,sizeof(now));
+}
+void *thread_screen_print(void *arg)
+{
+ struct FS_space_t* handle=(struct FS_space_t*)arg;
+ while(handle->create_thread)
+ {
+ FS_passive_output(handle);
+ sleep(handle->stat_cycle);
+ }
+ return NULL;
+}
+
+
diff --git a/support/MESA_fs2/src/field_stat2.h b/support/MESA_fs2/src/field_stat2.h
new file mode 100644
index 0000000..7201fd9
--- /dev/null
+++ b/support/MESA_fs2/src/field_stat2.h
@@ -0,0 +1,65 @@
+#ifndef H_SCREEN_STAT_H_INCLUDE
+#define H_SCREEN_STAT_H_INCLUDE
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+
+enum field_dsp_style_t
+{
+ FS_STYLE_FIELD=0,
+ FS_STYLE_COLUMN,
+ FS_STYLE_LINE,
+ FS_STYLE_STATUS
+};
+enum field_calc_algo
+{
+ FS_CALC_CURRENT=0,
+ FS_CALC_SPEED
+};
+enum field_op
+{
+ FS_OP_ADD=1,
+ FS_OP_SET
+};
+
+
+typedef void* screen_stat_handle_t;
+
+enum FS_option
+{
+ OUTPUT_DEVICE, //VALUE is a const char*, indicate a file path string, SIZE = strlen(string+'\0')+1.DEFAULT:output to stdout.
+ PRINT_MODE, //VALUE is an interger,1:Rewrite ,2: Append. SIZE=4,DEFALUT:REWRITE.
+ STAT_CYCLE, //VALUE is an interger idicate interval seconds of every output, SIZE=4 ,DEFUALT:2 seconds.
+ PRINT_TRIGGER, //VALUE is an interger,1:Do print,0: Don't print.SIZE=4.DEFAULT:1.
+ CREATE_THREAD,//VALUE is an interger,1: Create a print thread,0:not create,output by call passive_output function,
+ //and the STAT_CYCLE is meaningless.SIZE=4,DEFAULT:0.
+ ID_INVISBLE,//value is field_id/status_id/column_id, not output this string, SIZE=4,DEFAULT: shutdown NO one.
+};
+
+//Always success.
+screen_stat_handle_t FS_create_handle(void);
+
+int FS_set_para(screen_stat_handle_t handle, enum FS_option type,const void* value,int size);
+void FS_start(screen_stat_handle_t handle);
+void FS_stop(screen_stat_handle_t* handle);
+
+//return field_id/line_id/column_id greater than zero if success,return an interger less than zero if failed.
+int FS_register(screen_stat_handle_t handle,enum field_dsp_style_t style,enum field_calc_algo calc_type,const char* name);
+
+//numerator_id and denominator_id must be column/field/status style.
+//scaling: negative value: zoom in; positive value: zoom out;
+int FS_register_ratio(screen_stat_handle_t handle,int numerator_id,int denominator_id,int scaling,enum field_dsp_style_t style,enum field_calc_algo calc_type,const char* name);
+
+//id: when id's type is FIELD , column_id is ignore.
+int FS_operate(screen_stat_handle_t handle,int id,int column_id,enum field_op op,long long value);
+
+void FS_passive_output(screen_stat_handle_t handle);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+