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 #include <stdarg.h>
00031 #include "connector-trace.h"
00032
00033
00034
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
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
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
00099 if (namch != 0)
00100
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
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