connector-trace.cc

00001 /*
00002  * Copyright (c) 2006 Regents of the SIGNET lab, University of Padova.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the University of Padova (SIGNET lab) nor the 
00014  *    names of its contributors may be used to endorse or promote products 
00015  *    derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
00018  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 
00019  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
00020  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
00021  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
00022  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
00023  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
00024  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
00025  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
00026  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
00027  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00028  */
00029  
00030 #include <stdarg.h>
00031 #include "connector-trace.h"
00032  
00033 /* ======================================================================
00034    TCL Hooks for the simulator
00035    ====================================================================== */
00036 static class ConnectorTraceClass : public TclClass {
00037 public:
00038         ConnectorTraceClass() : TclClass("ConnectorTrace") {}
00039         TclObject* create(int, const char*const*) {
00040                 return (new ConnectorTrace());
00041         }
00042 } class_connector_trace;
00043 
00044 /*
00045 Static attributes and methods for ConnectorTrace
00046 */
00047 ClTracer* ConnectorTrace::clTr_ = 0;
00048 
00049 void ConnectorTrace::addTracer(ClMessageTracer *tr)
00050 {
00051         if(!clTr_)
00052                 clTr_ = new ClTracer();
00053         clTr_->addTracer(tr);
00054 }
00055 
00056 void ConnectorTrace::addCommonTracer(ClMessageTracer *tr)
00057 {
00058         if(!clTr_)
00059                 clTr_ = new ClTracer();
00060         clTr_->addCommonTracer(tr);
00061 }
00062 
00063 
00064 
00065 ConnectorTrace::ConnectorTrace() : dirToPlugin_('P'), dirToNodeCore_('N'), dirUp_('r'), dirDown_('s')
00066 {
00067         depth_ = DEFAULTDEPTH;
00068         bind("depth_", &depth_);
00069         
00070         pt_ = new BaseTrace;
00071         pt_->buffer()[0] = 0;
00072         bind("debug_", &debug_);
00073 }
00074 
00075 ConnectorTrace::~ConnectorTrace()
00076 {
00077         delete pt_;
00078         printf("Distruttore ConnectorTrace\n");
00079 }
00080 
00081 
00082 int ConnectorTrace::command(int argc, const char*const* argv)
00083 {
00084         Tcl& tcl = Tcl::instance();
00085         // SAME SET OF TRACE CLASS
00086 
00087         if (argc == 2) {
00088                 if (strcmp(argv[1], "detach") == 0) {
00089                         pt_->channel(0) ;
00090                         pt_->namchannel(0) ;
00091                         return (TCL_OK);
00092                 }
00093                 if (strcmp(argv[1], "flush") == 0) {
00094                         Tcl_Channel ch = pt_->channel();
00095                         Tcl_Channel namch = pt_->namchannel();
00096                         if (ch != 0) 
00097                                 pt_->flush(ch);
00098                                 //Tcl_Flush(pt_.channel());
00099                         if (namch != 0)
00100                                 //Tcl_Flush(pt_->namchannel());
00101                                 pt_->flush(namch);
00102                         return (TCL_OK);
00103                 }
00104                 if (strcmp(argv[1], "tagged") == 0) {
00105                         tcl.resultf("%d", pt_->tagged());
00106                         return (TCL_OK);
00107                 }
00108         } else if (argc == 3) {
00109                 if (strcmp(argv[1], "annotate") == 0) {
00110                         if (pt_->channel() != 0)
00111                                 annotate(argv[2]);
00112                         return (TCL_OK);
00113                 }
00114                 if (strcmp(argv[1], "attach") == 0) {
00115                         int mode;
00116                         const char* id = argv[2];
00117                         Tcl_Channel ch = Tcl_GetChannel(tcl.interp(), (char*)id,
00118                                                   &mode);
00119                         pt_->channel(ch); 
00120                         if (pt_->channel() == 0) {
00121                                 tcl.resultf("trace: can't attach %s for writing", id);
00122                                 return (TCL_ERROR);
00123                         }
00124                         return (TCL_OK);
00125                 }
00126                 if (strcmp(argv[1], "namattach") == 0) {
00127                         int mode;
00128                         const char* id = argv[2];
00129                         Tcl_Channel namch = Tcl_GetChannel(tcl.interp(), 
00130                                                            (char*)id, &mode);
00131                         pt_->namchannel(namch); 
00132                         if (pt_->namchannel() == 0) {
00133                                 tcl.resultf("trace: can't attach %s for writing", id);
00134                                 return (TCL_ERROR);
00135                         }
00136                         return (TCL_OK);
00137                 }
00138                 if (strcmp(argv[1], "ntrace") == 0) {
00139                         if (pt_->namchannel() != 0) 
00140                                 write_nam_trace(argv[2]);
00141                         return (TCL_OK);
00142                 }
00143                 if (strcmp(argv[1], "tagged") == 0) {
00144                         int tag;
00145                         if (Tcl_GetBoolean(tcl.interp(),
00146                                            (char*)argv[2], &tag) == TCL_OK) {
00147                                 pt_->tagged(tag);
00148                                 return (TCL_OK);
00149                         } else return (TCL_ERROR);
00150                 }
00151                 if (strcasecmp(argv[1],"traceToModule")==0)
00152                 {
00153                         dirToPlugin_ = argv[2][0];
00154                         return TCL_OK;
00155                 }
00156                 if (strcasecmp(argv[1],"traceToNodeCore")==0)
00157                 {
00158                         dirToNodeCore_ = argv[2][0];
00159                         return TCL_OK;
00160                 }
00161                 if (strcasecmp(argv[1],"traceUp")==0)
00162                 {
00163                         dirUp_ = argv[2][0];
00164                         return TCL_OK;
00165                 }
00166                 if (strcasecmp(argv[1],"traceDown")==0)
00167                 {
00168                         dirDown_ = argv[2][0];
00169                         return TCL_OK;
00170                 }
00171                 if (strcmp(argv[1], "preambleToPlugin") == 0)
00172                 {
00173                         sprintf(preambleToPlugin_, "%s", argv[2]);
00174                         return (TCL_OK);
00175                 }
00176                 if (strcmp(argv[1], "preambleToNodeCore") == 0)
00177                 {
00178                         sprintf(preambleToNodeCore_, "%s", argv[2]);
00179                         return (TCL_OK);
00180                 }
00181                 if (strcmp(argv[1], "preambleUp") == 0)
00182                 {
00183                         sprintf(preambleUp_, "%s", argv[2]);
00184                         return (TCL_OK);
00185                 }
00186                 if (strcmp(argv[1], "preambleDown") == 0)
00187                 {
00188                         sprintf(preambleDown_, "%s", argv[2]);
00189                         return (TCL_OK);
00190                 }
00191 
00192         }
00193         return TclObject::command(argc, argv);
00194 }
00195 
00196 int ConnectorTrace::depth()
00197 {
00198         return (depth_);
00199 }
00200 
00201 
00202 void ConnectorTrace::write_nam_trace(const char *s)
00203 {
00204         sprintf(pt_->nbuffer(), "%s", s);
00205         pt_->namdump();
00206 }
00207 
00208 void ConnectorTrace::annotate(const char* s)
00209 {
00210         if (pt_->tagged()) {
00211                 sprintf(pt_->buffer(),
00212                         "v "TIME_FORMAT" -e {sim_annotation %g %s}",
00213                         Scheduler::instance().clock(), 
00214                         Scheduler::instance().clock(), s);
00215         } else {
00216                 sprintf(pt_->buffer(),
00217                         "v "TIME_FORMAT" eval {set sim_annotation {%s}}", 
00218                         pt_->round(Scheduler::instance().clock()), s);
00219         }
00220         pt_->dump();
00221         //callback();
00222         sprintf(pt_->nbuffer(), "v -t "TIME_FORMAT" -e sim_annotation %g %s", 
00223                 Scheduler::instance().clock(), 
00224                 Scheduler::instance().clock(), s);
00225         pt_->namdump();
00226 }
00227 
00228 void ConnectorTrace::writeTrace(char* s, ...)
00229 {
00230         va_list ap;
00231         va_start(ap, s);
00232         int offset = strlen(pt_->buffer());
00233         int remain = BASICTRACE_BUFFERLEN - offset - 2;
00234         vsnprintf(pt_->buffer()+offset, remain, s, ap);
00235         va_end(ap);
00236 }
00237 
00238 void ConnectorTrace::vWriteTrace(char* s, va_list ap)
00239 {
00240         int offset = strlen(pt_->buffer());
00241         int remain = BASICTRACE_BUFFERLEN - offset - 2;
00242         vsnprintf(pt_->buffer()+offset, remain, s, ap);
00243 }
00244 
00245 void ConnectorTrace::dump()
00246 {
00247         if(pt_)
00248                 pt_->dump();
00249         pt_->buffer()[0] = 0;
00250 }
00251 
00252 
00253 void ConnectorTrace::handle(Event *e)
00254 {       
00255 }
00256 
00257 void ConnectorTrace::trace(ClMessage* m)
00258 {
00259         if(m->direction() == TONODECORE)
00260                 writeTrace("%c %.9f %s ASYNC",dirToNodeCore_, Scheduler::instance().clock(), preambleToNodeCore_);
00261         else if(m->direction() == TOMODULE)
00262                 writeTrace("%c %.9f %s ASYNC",dirToPlugin_, Scheduler::instance().clock(), preambleToPlugin_);
00263         else if(m->direction() == UP)
00264                 writeTrace("%c %.9f %s ASYNC",dirUp_, Scheduler::instance().clock(), preambleUp_);
00265         else
00266                 writeTrace("%c %.9f %s ASYNC",dirDown_, Scheduler::instance().clock(), preambleDown_);
00267         if(clTr_)
00268                 clTr_->trace(m, this);
00269         dump();
00270 }
00271 
00272 void ConnectorTrace::traceSync(ClMessage* m)
00273 {
00274         if(m->direction() == TONODECORE)
00275                 writeTrace("%c %.9f %s SYNC",dirToNodeCore_, Scheduler::instance().clock(), preambleToNodeCore_);
00276         else
00277                 writeTrace("%c %.9f %s SYNC",dirToPlugin_, Scheduler::instance().clock(), preambleToPlugin_);
00278         if(clTr_)
00279                 clTr_->trace(m, this);
00280         dump();
00281 }
00282 
00283 

Generated on Wed Nov 26 15:47:28 2008 for NS-MIRACLE library by  doxygen 1.5.2