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
00038
00039
00040
00041
00042
00043
00044 # include <stdio.h>
00045 # include <stdlib.h>
00046 # include <string.h>
00047 # include <sys/types.h>
00048 # include <fcntl.h>
00049 # include <signal.h>
00050 # include <unistd.h>
00051 # include <Profile/Profiler.h>
00052
00053
00054 # if ( !defined(__ksr__) || defined(UNIPROC) )
00055 # define __private
00056 # endif
00057
00058 # define PCXX_EVENT_SRC
00059 # define TRACING_ON 1
00060 # include "pcxx_events.h"
00061
00062
00063
00064
00065 extern time_t time(time_t * t);
00066
00067 __private unsigned long int pcxx_ev_class = PCXX_EC_TRACER | PCXX_EC_TIMER;
00068
00069 # ifndef TRUE
00070 # define FALSE 0
00071 # define TRUE 1
00072 # endif
00073
00074
00075 __private static PCXX_EV pcxx_buf[PCXX_BUFSIZE];
00076
00077
00078 __private PCXX_EV *pcxx_ev_ptr = pcxx_buf;
00079
00080
00081
00082 __private PCXX_EV *pcxx_ev_max = pcxx_buf + PCXX_BUFSIZE - 1;
00083
00084
00085 __private static int pcxx_fd;
00086
00087
00088 __private static int pcxx_num_init[PCXX_MAXPROCS];
00089
00090
00091
00092
00093 long pcxx_GetUSecLong(void)
00094 {
00095 return (long) RtsLayer::getUSecD();
00096 }
00097
00098 static void pcxx_EventOnly(long int ev,long int par)
00099 {
00100 pcxx_ev_ptr->ev = ev;
00101 pcxx_ev_ptr->ti = pcxx_GetUSecLong();
00102 pcxx_ev_ptr->par = par;
00103 pcxx_ev_ptr->nid = PCXX_MYNODE;
00104 pcxx_ev_ptr->tid = PCXX_MYTHREAD;
00105 pcxx_ev_ptr++;
00106 }
00107
00108
00109 void pcxx_EvFlush()
00110 {
00111 static PCXX_EV flush_end = { PCXX_EV_FLUSH_EXIT, 0, 0, 0L };
00112
00113 if ( pcxx_ev_ptr != pcxx_buf )
00114 {
00115 if ( pcxx_ev_class & PCXX_EC_TRACER )
00116 pcxx_EventOnly (PCXX_EV_FLUSH_ENTER, pcxx_ev_ptr - pcxx_buf);
00117
00118 write (pcxx_fd, pcxx_buf, (pcxx_ev_ptr - pcxx_buf) * sizeof(PCXX_EV));
00119 if ( pcxx_ev_class & PCXX_EC_TRACER )
00120 {
00121 flush_end.nid = PCXX_MYNODE;
00122 flush_end.ti = pcxx_GetUSecLong();
00123 write (pcxx_fd, &flush_end, sizeof(PCXX_EV));
00124 }
00125 pcxx_ev_ptr = pcxx_buf;
00126 }
00127 }
00128
00129
00130 # ifndef NSIG
00131 # define NSIG 32
00132 # endif
00133 static SIGNAL_TYPE (*sighdlr[NSIG])(SIGNAL_ARG_TYPE);
00134
00135 static void wrap_up(int sig)
00136 {
00137 fprintf (stderr, "signal %d on %d - flushing event buffer...\n", sig, PCXX_MYNODE);
00138 pcxx_EvFlush ();
00139 fprintf (stderr, "done.\n");
00140 if ( sighdlr[sig] != SIG_IGN ) (* sighdlr)(sig);
00141 exit (1);
00142 }
00143
00144 static void init_wrap_up()
00145 {
00146 # ifdef SIGINT
00147 sighdlr[SIGINT ] = signal (SIGINT , wrap_up);
00148 # endif
00149 # ifdef SIGQUIT
00150 sighdlr[SIGQUIT] = signal (SIGQUIT, wrap_up);
00151 # endif
00152 # ifdef SIGILL
00153 sighdlr[SIGILL ] = signal (SIGILL , wrap_up);
00154 # endif
00155 # ifdef SIGFPE
00156 sighdlr[SIGFPE ] = signal (SIGFPE , wrap_up);
00157 # endif
00158 # ifdef SIGBUS
00159 sighdlr[SIGBUS ] = signal (SIGBUS , wrap_up);
00160 # endif
00161 # ifdef SIGTERM
00162 sighdlr[SIGTERM] = signal (SIGTERM, wrap_up);
00163 # endif
00164 # ifdef SIGABRT
00165 sighdlr[SIGABRT] = signal (SIGABRT, wrap_up);
00166 # endif
00167 # ifdef SIGSEGV
00168 sighdlr[SIGSEGV] = signal (SIGSEGV, wrap_up);
00169 # endif
00170 }
00171
00172
00173 void pcxx_EvInit(char *name)
00174 {
00175 char *ptr;
00176 char *ptr1;
00177 PCXX_EV *pcxx_iter = pcxx_buf;
00178
00179 static int first_time = 0;
00180
00181
00182 if (first_time == 0)
00183 {
00184 first_time = 1;
00185 # ifdef UNIPROC
00186 ptr = name;
00187 # else
00188 ptr = (char *) PCXX_MALLOC (strlen(name) + 1);
00189 strcpy (ptr, name);
00190 if ( ptr1 = strchr (ptr, '#') )
00191 {
00192 *ptr1++ = PCXX_MYNODE / 1000 + '0';
00193 *ptr1++ = PCXX_MYNODE % 1000 / 100 + '0';
00194 *ptr1++ = PCXX_MYNODE % 100 / 10 + '0';
00195 *ptr1 = PCXX_MYNODE % 10 + '0';
00196 }
00197 else
00198 {
00199 fprintf (stderr, "%s: trace file name does not contain '####'\n", name);
00200 exit (1);
00201 }
00202 # endif
00203
00204 init_wrap_up ();
00205
00206 if ((pcxx_fd = open (ptr, O_WRONLY|O_CREAT|O_TRUNC|O_APPEND, 0600)) < 0)
00207 {
00208 fprintf (stderr, "pcxx_EvInit[open]: ");
00209 perror (ptr);
00210 exit (1);
00211 }
00212
00213
00214 if ((&pcxx_buf[0])->ev == PCXX_EV_INIT)
00215 {
00216 for(pcxx_iter = pcxx_buf; pcxx_iter != pcxx_ev_ptr ; pcxx_iter++)
00217 {
00218 pcxx_iter->nid = PCXX_MYNODE;
00219 }
00220 }
00221 else
00222 {
00223
00224 if (pcxx_ev_ptr == pcxx_buf)
00225 {
00226 pcxx_Event(PCXX_EV_INIT, pcxx_ev_class);
00227 }
00228 else
00229 {
00230 printf("Warning: pcxx_EvInit(): First record is not INIT\n");
00231 }
00232 }
00233
00234 if ( pcxx_ev_class & PCXX_EC_TRACER )
00235 pcxx_Event (PCXX_EV_WALL_CLOCK, time((time_t *)0));
00236 }
00237 pcxx_num_init[PCXX_MYNODE]++;
00238
00239 }
00240
00241
00242 void pcxx_Event(long int ev, long int par)
00243 {
00244 static int first_time = 0;
00245 if (first_time == 0)
00246 {
00247 if (ev != PCXX_EV_INIT)
00248 {
00249 pcxx_ev_ptr = pcxx_buf;
00250
00251 pcxx_ev_ptr->ev = PCXX_EV_INIT;
00252 pcxx_ev_ptr->ti = pcxx_GetUSecLong();
00253 pcxx_ev_ptr->par = pcxx_ev_class;
00254
00255 pcxx_ev_ptr->nid = PCXX_MYNODE;
00256 pcxx_ev_ptr->tid = PCXX_MYTHREAD;
00257
00258 pcxx_ev_ptr++;
00259 }
00260 first_time = 1;
00261 }
00262
00263 pcxx_ev_ptr->ev = ev;
00264 pcxx_ev_ptr->ti = pcxx_GetUSecLong();
00265 pcxx_ev_ptr->par = par;
00266 pcxx_ev_ptr->nid = PCXX_MYNODE;
00267 pcxx_ev_ptr->tid = PCXX_MYTHREAD;
00268 pcxx_ev_ptr++;
00269
00270 if ( pcxx_ev_ptr >= pcxx_ev_max ) pcxx_EvFlush ();
00271 }
00272
00273
00274 void pcxx_EvClose()
00275 {
00276 pcxx_num_init[PCXX_MYNODE]--;
00277 if ( pcxx_num_init[PCXX_MYNODE] == 0 )
00278 {
00279 if ( pcxx_ev_class & PCXX_EC_TRACER )
00280 {
00281 pcxx_Event (PCXX_EV_CLOSE, 0);
00282 pcxx_Event (PCXX_EV_WALL_CLOCK, time((time_t *)0));
00283 }
00284 pcxx_EvFlush ();
00285 close (pcxx_fd);
00286 }
00287 }
00288
00289
00290 # define CONT_EV_LEN (sizeof(PCXX_EV) - sizeof(long int))
00291
00292 void pcxx_LongEvent(long int ev, int ln, char *par)
00293 {
00294 char *buf;
00295 int i, j, cev_no;
00296
00297 cev_no = ln / CONT_EV_LEN + ((ln % CONT_EV_LEN) > 0);
00298
00299
00300 pcxx_ev_ptr->ev = ev;
00301 pcxx_ev_ptr->ti = pcxx_GetUSecLong();
00302 pcxx_ev_ptr->par = ln;
00303 pcxx_ev_ptr->nid = PCXX_MYNODE;
00304 pcxx_ev_ptr->tid = PCXX_MYTHREAD;
00305 pcxx_ev_ptr++;
00306 if ( pcxx_ev_ptr >= pcxx_ev_max ) pcxx_EvFlush ();
00307
00308
00309 if ( ln )
00310 {
00311 for (i=0; i<cev_no; i++)
00312 {
00313 pcxx_ev_ptr->ev = PCXX_EV_CONT_EVENT;
00314 buf = ((char *) pcxx_ev_ptr) + sizeof(short unsigned int);
00315 for (j=0; j<CONT_EV_LEN; j++)
00316 *buf++ = (i*CONT_EV_LEN+j) < ln ? *par++ : '\0';
00317 pcxx_ev_ptr++;
00318 if ( pcxx_ev_ptr >= pcxx_ev_max ) pcxx_EvFlush ();
00319 }
00320 }
00321 }
00322
00323 #if ( defined(TRACING_ON) && defined(ARIADNE_SUPPORT) )
00324
00325 void pcxx_AriadneTrace (long int event_class, long int event, int pid, int oid, int rwtype, int mtag, int par)
00326 {
00327
00328 long int trace_value = 0L;
00329 long int parameter = 0L;
00330
00331
00332
00333
00334 parameter = (long int) par;
00335
00336 if (sizeof (long int) == 8)
00337 {
00338
00339
00340 trace_value = (parameter << 32) | (pid << 22) | (oid << 12) | (rwtype << 8) | mtag;
00341
00342
00343
00344
00345
00346 PCXX_EVENT(event_class, event, trace_value);
00347 }
00348
00349 }
00350
00351 #endif
00352
00353
00354
00355
00356
00357
00358
00359
00360