00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <stdio.h>
00038 #include <string.h>
00039 #include <vector>
00040 #include <math.h>
00041 #include <assert.h>
00042 #include <iostream>
00043 #include "wmp_config.h"
00044
00045 #include "core/include/frames.h"
00046 #include "bridge.hh"
00047 #include "core/interface/Msg.h"
00048 #include "window2.hh"
00049 #include "statistics.h"
00050 #include "basic_io.h"
00051 #include "stats.h"
00052 #include "graphs.h"
00053 #include <map>
00054 #include "Stats.h"
00055 #include "Plotter.h"
00056 using namespace std;
00057
00058 ThingOverTimeCStats<long long, int> timespan("Interval","us");
00059
00060 PlainCStats<int> tkns("Tokens","");
00061 PlainCStats<int> msgs("Messages","");
00062 PlainCStats<int> auths("Authorizations","");
00063
00064 PlainCStats<long long> th_wc("Calculated WC Loop","us");
00065 PlainCStats<long long> th_bc_wc("Calculated WC BC Loop","us");
00066
00067 MaxMinCStats<long long> paps("PAP Duration","us");
00068 MaxMinCStats<long long> loops("LOOP Duration","us");
00069 MaxMinCStats<long long> wc_loops("WC LOOP Duration","us");
00070 MaxMinCStats<long long> inter_token("Inter-Token","us");
00071 MaxMinCStats<long long> inter_message("Inter-Message","us");
00072 MaxMinCStats<long long> inter_auth("Inter-Auth","us");
00073 MaxMinCStats<long long> inter_fore("Inter-Foreign","us");
00074 MaxMinCStats<long long> loop_length("Loop length","hops");
00075 MaxMinCStats<long long> bc_loop("BC Loop duration","us");
00076
00077 ListCStats<long long> reinserted("Reinserted","Serial");
00078 ListCStats<long long> retries("Retries","Serial");
00079 ListCStats<int> ncs("Not Consecutive Serial","Id");
00080 ListCStats<int> incongruent("Incongruent Cases","Id");
00081 ListCStats<int> drops("Drops","Drop Serial");
00082 ListCStats<int> ett("ETT","Extra time (ms) ");
00083 ListCStats<int> plrx("Possibly Lost in RX","Serial");
00084 ListCStats<int> foreign("Foreign Frames","Id");
00085 ListCStats<long long> stops("Stops","ms");
00086 ListCStats<long long> qos_stops("Messages Stop","Serial");
00087
00088 IntervalCStats<int> efz("Max Error Free Zone","Frames");
00089 IntervalCStats<int> mmz("Max Message Zone","Frames");
00090
00091 Plotter< MaxMinCStats<long long>, long long > plotter;
00092
00093 std::map<int, StatsFlow *> flows;
00094
00095 std::map<unsigned int, long long> bc_map;
00096 long long last_ptime = 0, first_time;
00097 int last_pos = 0;
00098 bool first = false;
00099 char last_frame[2500];
00100 int total_frames = 0;
00101 bool first_frame = true;
00102
00103
00104 static int nnodes = 0, from, to;
00105 static window2 * w2;
00106 static int lastForeignTime = 0;
00107 long long lastIat;
00108 unsigned long long old_qosPh_serial = 0;
00109 FILE * outf;
00110 static bool flows_initied = false;
00111
00112 void statistics_init_flows() {
00113 if (!flows_initied){
00114 flows_initied = true;
00115 std::map<int, StatsFlow * >::iterator iter;
00116 for (iter = flows.begin(); iter != flows.end(); ++iter) {
00117 delete iter->second;
00118 }
00119 flows.clear();
00120
00121 flows[0] = new StatsFlow(-1,-1,-1,0);
00122 for (int i = 0; i < nnodes; i++) {
00123 flows[10000+i] = new StatsFlow(10000+i, i, -2, 0, first_time);
00124 for (int j = 0; j < nnodes; j++) {
00125 int flow_id = j * 100 + i + 1;
00126 int pernode_id = i + 10000;
00127 flows[flow_id] = new StatsFlow(flow_id, i, j, 0, first_time);
00128 }
00129 }
00130 }
00131 }
00132
00133 int statistics_from_file(char * filename, int & begin, int & end){
00134 nnodes=io_open_sim_data(filename);
00135 int n=0;
00136 if (nnodes>0) {
00137 n=io_get_sim_data_num_of_elements();
00138 } else {
00139 return -1;
00140 }
00141 if (begin<0 || to <0){
00142 from=0;
00143 to=n;
00144 }else{
00145 from=begin;
00146 to=end;
00147 }
00148 io_go_to(from);
00149
00150 int idx=0;
00151 char fdata[2700];
00152 long long base_time = 0;
00153 simData_Hdr * p = (simData_Hdr *) fdata;
00154 wmpFrame * r = (wmpFrame *) (fdata + sizeof(simData_Hdr));
00155
00156 fprintf(stderr,"Generating Statistics...\n");
00157 first_frame = true;
00158 for (int i=from; i<to; i++) {
00159 int bytes=io_read_next_sim_data(&fdata[0]);
00160 if (i==from) base_time=p->time;
00161 if (bytes > 0){
00162 statistics_new_frame(r,p->time-base_time,i,bytes,p);
00163 printf("Analizing Data %3.1f %c \r",100.0*double(i-from)/double(to-from),'%');
00164 }else{
00165 break;
00166 }
00167 idx++;
00168 }
00169
00170 efz.done();
00171 mmz.done();
00172
00173 begin=from;
00174 end=from+idx;
00175 return idx;
00176 }
00177
00178 void statistics_get_fez(int & min, int & max){
00179 CStats<int>::stat_t mi = efz.getIntervalMin();
00180 CStats<int>::stat_t ma = efz.getIntervalMax();
00181 min = mi.pos;
00182 max = ma.pos;
00183 }
00184
00185
00186
00187 int hf(int key)
00188 {
00189 int c2=0x27d4eb2d;
00190 key = (key ^ 61) ^ (key >> 16);
00191 key = key + (key << 3);
00192 key = key ^ (key >> 4);
00193 key = key * c2;
00194 key = key ^ (key >> 15);
00195 return key;
00196 }
00197
00198 void statistics_init() {
00199 outf= fopen("outf.txt","w+");
00200
00201 flows_initied = false;
00202
00203 tkns.init();
00204 msgs.init();
00205 auths.init();
00206 th_wc.init();
00207 th_bc_wc.init();
00208
00209 paps.init();
00210 loops.init();
00211 wc_loops.init();
00212
00213 inter_token.init();
00214 inter_message.init();
00215 inter_auth.init();
00216 inter_fore.init();
00217
00218 loop_length.init();
00219
00220 reinserted.init();
00221 retries.init();
00222 ncs.init();
00223 incongruent.init();
00224 drops.init();
00225 ett.init();
00226 plrx.init();
00227
00228 efz.init();
00229 mmz.init();
00230 timespan.init();
00231 foreign.init();
00232 stops.init();
00233 qos_stops.init();
00234
00235 bc_loop.init();
00236
00237 lastForeignTime = 0;
00238 }
00239
00240 bool last_pap_jump(wmpFrame * p){
00241 int sum = 0, idx = 0;
00242 char * pnt = wmp_get_frame_routing_pointer(p, nnodes);
00243 for (int j = 0; j < nnodes; j++) {
00244 #ifdef WMP_ROUTING_tree
00245 unsigned char reached = *(pnt+nnodes+j);
00246 #else
00247 unsigned char reached = pnt[j * (nnodes + 1)];
00248 #endif
00249 if (!(reached & 128)) {
00250 sum += 1;
00251 idx = j;
00252 }
00253 }
00254
00255 if (sum == 1 && idx == p->hdr.to) {
00256 return true;
00257 }else{
00258 return false;
00259 }
00260
00261 }
00262
00263 bool new_token(wmpFrame * p){
00264 return false;
00265 }
00266
00267 void statistics_new_frame(wmpFrame * p, long long ptime, int pos, int bytes, simData_Hdr * sdh) {
00268 if (pos == from){
00269 last_ptime = ptime;
00270 last_pos = pos;
00271 first_time = ptime;
00272 }
00273
00274 statistics_init_flows();
00275
00276 if (!sdh->is_wmp){
00277 foreign.new_value(pos,pos);
00278 if (lastForeignTime != 0){
00279 inter_fore.new_value(last_ptime - lastForeignTime, pos);
00280 }
00281 lastForeignTime = ptime;
00282 return;
00283 }
00284 if (ptime - last_ptime > 400000){
00285 stops.new_value(ptime/1000 - last_ptime/1000,pos);
00286 }
00287 qos_stops.new_touch();
00288 stops.new_touch();
00289 foreign.new_touch();
00290 ncs.new_touch();
00291 incongruent.new_touch();
00292 retries.new_touch();
00293 reinserted.new_touch();
00294 drops.new_touch();
00295 plrx.new_touch();
00296 ett.new_touch();
00297 bc_loop.new_touch();
00298
00299 wmpFrame * q = (wmpFrame *) last_frame;
00300 efz.new_value(pos,pos);
00301 timespan.new_time(ptime);
00302
00303
00304 if (p->hdr.serial != q->hdr.serial + 1 && !first_frame){
00305 ncs.new_value(pos,pos);
00306 loop_length.aux2 = 0;
00307 efz.reset();
00308 }
00309
00310 first_frame = false;
00311
00312 if (p->hdr.serial == q->hdr.serial + 2){
00313 plrx.new_value(q->hdr.serial+1,pos);
00314 }
00315
00316 if (p->hdr.type == DROP_TOKEN){
00317 drops.new_value(p->drop.drop_serial,pos);
00318 efz.reset();
00319 }
00320
00321 if (q->hdr.type == AUTHORIZATION && p->hdr.type == TOKEN){
00322 incongruent.new_value(last_pos,last_pos);
00323
00324 }
00325
00326 if (q->hdr.type == TOKEN && p->hdr.type == TOKEN){
00327 inter_token.new_value(ptime-last_ptime,pos);
00328 }
00329 if (q->hdr.type == AUTHORIZATION && p->hdr.type == AUTHORIZATION){
00330 inter_auth.new_value(ptime-last_ptime,pos);
00331 }
00332 if (q->hdr.type == MESSAGE && p->hdr.type == MESSAGE){
00333 inter_message.new_value(ptime-last_ptime,pos);
00334 }
00335
00336 if (p->hdr.retries !=0 ){
00337 retries.new_value(p->hdr.serial,pos);
00338 loop_length.aux2 = 0;
00339 }
00340
00341 if (sdh->reinserted == 32){
00342 reinserted.new_value(p->hdr.serial,pos);
00343 }
00344
00345 if (p->hdr.type == TOKEN){
00346 tkns.new_value(1);
00347 bool is_new_token = new_token(p);
00348 bool is_last_pap_jump = last_pap_jump(p);
00349
00350 if (is_new_token){
00351 paps.bookmark = last_ptime;
00352 paps.aux1 = 1;
00353 loops.bookmark = last_ptime;
00354 loop_length.aux1 = 0;
00355 loop_length.aux2 = 1;
00356 if (mmz.aux1 == 0){
00357 mmz.reset();
00358 }
00359 mmz.aux1 = 0;
00360 }
00361 if (paps.aux1==1 && is_last_pap_jump){
00362 paps.new_value(ptime-paps.bookmark,pos);
00363 }
00364 }else{
00365 paps.aux1 = 0;
00366 }
00367
00368 loop_length.aux1++;
00369
00370 if (p->hdr.type == AUTHORIZATION){
00371 auths.new_value(1);
00372
00373 }
00374
00375 if (p->hdr.type == MESSAGE) {
00376 msgs.new_value(1);
00377
00378 bool is_last_msg_jump = (p->msg.dest & (1 << p->hdr.to));
00379 if (p->hdr.retries == 0) {
00380
00381 if (loop_length.aux2 == 1) {
00382 loop_length.new_value(loop_length.aux1, pos);
00383 loops.new_value(ptime - loops.bookmark, pos);
00384 if (loop_length.aux1
00385 == ((2 * nnodes - 3) + (nnodes - 1) + (nnodes - 1))) {
00386 wc_loops.new_value(ptime - loops.bookmark, pos);
00387 }
00388 }
00389 }
00390
00391 mmz.new_value(pos, pos);
00392 mmz.aux1 = 1;
00393 }
00394
00395 std::map<int, StatsFlow * >::iterator iter;
00396 for (iter = flows.begin(); iter != flows.end(); ++iter) {
00397 iter->second->new_frame(p,ptime,pos);
00398 }
00399
00400
00401 last_ptime = ptime;
00402 last_pos = pos;
00403 total_frames++;
00404 memcpy(last_frame,p,bytes);
00405 }
00406
00407 template <class T>
00408 void publish(MaxMinCStats<T> mms, int precision=0, int uid=-1){
00409 if (mms.isValid()){
00410 if (uid==-1){
00411
00412 w2->row_create(mms.getName()+ " (" + toString(mms.getCount())+ ")",toString(mms.getMean(),precision)+" " + mms.getUnit() , -1, uid);
00413 } else {
00414 w2->row_create(mms.getName()+"*"+ " (" + toString(mms.getCount()) + ")",toString(mms.getMean(),precision)+" " + mms.getUnit(), -1, uid);
00415 }
00416 typename CStats<T>::stat_t val = mms.getMax();
00417 w2->subSectionBegin();
00418 w2->row_create("Max",toString(val.value,precision)+" " + mms.getUnit(),val.pos);
00419 val = mms.getMin();
00420 w2->row_create("Min",toString(val.value,precision)+" " + mms.getUnit(),val.pos);
00421 w2->subSectionEnd();
00422 }
00423 }
00424
00425 template <class T>
00426 void publish(IntervalCStats<T> mms, int precision=0){
00427 if (mms.isValid()){
00428 w2->row_create(mms.getName(),toString(mms.getIntervalCount(),precision)+" " + mms.getUnit());
00429 typename CStats<T>::stat_t val = mms.getIntervalMin();
00430 w2->subSectionBegin();
00431 w2->row_create("From",toString(val.value,precision)+" " + mms.getUnit(),val.pos);
00432 val = mms.getIntervalMax();
00433 w2->row_create("To",toString(val.value,precision)+" " + mms.getUnit(),val.pos);
00434 w2->subSectionEnd();
00435 }
00436 }
00437
00438 template <class T>
00439 void publish(DoubleListCStats<T> lcs, int precision=0){
00440 w2->row_create(lcs.getName(),toString(lcs.getCount()) + " (" + toString(lcs.getPercentage(),3) + "%)");
00441 w2->subSectionBegin();
00442 typename CStats<T>::stat_t val1,val2;
00443 for (int i=0; i< lcs.getCount();i++){
00444 lcs.getElem(i,val1,val2);
00445 w2->row_create(lcs.getChildName(),toString(val1.value,precision),-1);
00446 w2->subSectionBegin();
00447 w2->row_create("Begin",toString(val1.pos,precision),val1.pos);
00448 w2->row_create("End",toString(val2.pos,precision),val2.pos);
00449 w2->subSectionEnd();
00450 }
00451 w2->subSectionEnd();
00452 }
00453
00454
00455 template <class T>
00456 void publish(ListCStats<T> lcs, int precision=0){
00457 w2->row_create(lcs.getName(),toString(lcs.getCount()) + " (" + toString(lcs.getPercentage(),3) + "%)");
00458 w2->subSectionBegin();
00459 typename CStats<T>::stat_t val;
00460 for (int i=0; i< lcs.getCount();i++){
00461 val = lcs.getElem(i);
00462 w2->row_create(lcs.getChildName(),toString(val.value,precision),val.pos);
00463 }
00464 w2->subSectionEnd();
00465 }
00466
00467 template <class T>
00468 void publish(PlainCStats<T> pcs, int precision=0){
00469 w2->row_create(pcs.getName(),toString(pcs.getSum(),precision) + " " + pcs.getUnit());
00470 }
00471 template <class T,class P>
00472
00473 void publish(ThingOverTimeCStats<T,P> tot, int precision=0){
00474 w2->row_create(tot.getName(),toString(tot.getToT(),precision) + " " + tot.getUnit());
00475 }
00476 void stat_plot_tg(int i){
00477 plotter.plot(i);
00478 }
00479 void stat_write_to_file(int i){
00480 plotter.write_to_file(i);
00481 }
00482 void stat_plot_hist(int i, int nbins, double zoom){
00483 plotter.plotHist(i, nbins, zoom);
00484 }
00485
00486 void statistics_publish(window2 * w) {
00487 w2=w;
00488
00489 plotter.clear();
00490 w2->root();
00491
00492 int m = timespan.getInterval()/(1000*1000*60);
00493 int s = (timespan.getInterval()%(1000*1000*60))/(1000*1000);
00494 int ms = (timespan.getInterval()%(1000*1000*60))%(1000*1000)/1000;
00495 th_wc.new_value((2*nnodes-3)*inter_token.getMean()+(nnodes-1)*inter_auth.getMean()+(nnodes-1)*inter_message.getMean());
00496 th_bc_wc.new_value((4*nnodes-9)*inter_token.getMean());
00497
00498 w2->row_create("Trace Duration",toString(m)+"m "+toString(s)+"s " + toString(ms)+"ms");
00499 w2->root();
00500 w2->row_create("General","");
00501 w2->subSectionBegin();
00502 publish(tkns);
00503 publish(auths);
00504 publish(msgs);
00505 publish(foreign);
00506 w2->row_create("InterFrame","");
00507 w2->subSectionBegin();
00508 publish(inter_token, 0, plotter.subscribe(&inter_token,w2->getCurrentRowName()));
00509 publish(inter_auth, 0, plotter.subscribe(&inter_auth,w2->getCurrentRowName()));
00510 publish(inter_message, 0, plotter.subscribe(&inter_message,w2->getCurrentRowName()));
00511 publish(inter_fore, 0, plotter.subscribe(&inter_fore,w2->getCurrentRowName()));
00512
00513 w2->root();
00514 w2->row_create("Duration","");
00515 w2->subSectionBegin();
00516 publish(paps,0,plotter.subscribe(&paps,w2->getCurrentRowName()));
00517 publish(loops,0,plotter.subscribe(&loops,w2->getCurrentRowName()));
00518 publish(wc_loops,0,plotter.subscribe(&wc_loops,w2->getCurrentRowName()));
00519
00520
00521
00522 w2->root();
00523 w2->row_create("Errors","");
00524 w2->subSectionBegin();
00525 publish(ncs);
00526
00527 publish(retries);
00528 publish(drops);
00529 publish(plrx);
00530
00531 w2->root();
00532
00533
00534
00535
00536
00537 w2->root();
00538 w2->row_create("Intervals","");
00539 w2->subSectionBegin();
00540 publish(efz);
00541
00542
00543 std::map<int, StatsFlow * >::iterator iter;
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569 w2->root();
00570 w2->row_create("Flows","");
00571 w2->subSectionBegin();
00572
00573
00574 int i, size = flows.size();
00575 for (iter = flows.begin(), i = 1; iter != flows.end(); ++iter,i++) {
00576 printf("Processing Data %3.1f %c\r",100.0*double(i)/double(size),'%');
00577 fflush(stdout);
00578 if (!iter->second->is_qos()) {
00579 if (iter->first == 0) {
00580 w2->row_create("Global Flow", "");
00581 } else if (iter->first < 10000 && iter->second->get_count() > 0){
00582 w2->row_create("Flow :: Src: " + toString(
00583 iter->second->get_src()) + " Dst: " + toString(
00584 iter->second->get_dst()),"", iter->second->begin());
00585 } else if (iter->first >= 10000) {
00586 w2->row_create("Node # " + toString(
00587 iter->second->get_src()),"", iter->second->begin());
00588 }
00589 w2->subSectionBegin();
00590 iter->second->process();
00591 publish(iter->second->getNMsg(), 2);
00592 publish(iter->second->getBw(), 2);
00593 publish(iter->second->getNrd(), 2);
00594 publish(iter->second->getMdd(), 0, plotter.subscribe(&iter->second->getMdd(),w2->getCurrentRowName(),1000));
00595 publish(iter->second->getPapMdd(), 0, plotter.subscribe(&iter->second->getPapMdd(),w2->getCurrentRowName(),1000));
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606 w2->row_create("By Priority (Ages)", "");
00607 w2->subSectionBegin();
00608 iter->second->getBegin();
00609 while (iter->second->hasMore()){
00610 int id = iter->second->getId();
00611 MaxMinCStats<long long> & npl = iter->second->getNextPrioLoop();
00612 if (id >= 2000){
00613 publish(npl, 2,plotter.subscribe(&npl,w2->getCurrentRowName(),1000));
00614 }
00615 }
00616 w2->subSectionEnd();
00617
00618 w2->row_create("By Priority", "");
00619 w2->subSectionBegin();
00620 iter->second->getBegin();
00621 while (iter->second->hasMore()){
00622 int id = iter->second->getId();
00623 MaxMinCStats<long long> & npl = iter->second->getNextPrioLoop();
00624 if (id < 1000){
00625 publish(npl, 2,plotter.subscribe(&npl,w2->getCurrentRowName(),1000));
00626 }
00627 }
00628 w2->subSectionEnd();
00629
00630 w2->row_create("By Priority + age", "");
00631 w2->subSectionBegin();
00632 iter->second->getBegin();
00633 while (iter->second->hasMore()) {
00634 int id = iter->second->getId();
00635 MaxMinCStats<long long> & npl = iter->second->getNextPrioLoop();
00636 if (id >= 1000){
00637 publish(npl, 2, plotter.subscribe(&npl,w2->getCurrentRowName(),1000));
00638 }
00639 }
00640 w2->subSectionEnd();
00641 w2->subSectionEnd();
00642 }
00643 }
00644 w2->subSectionEnd();
00645 printf("\nDone.\n");
00646
00647 fflush(stdout);
00648 plotter.writeAll(w->getFileName());
00649 }
00650
00651 bool stat_ask_plotter(int i){
00652 return plotter.hasThis(i);
00653 }