back out change to separate event type and timestamp streams, one stream supports...
[IRC.git] / Robust / src / Runtime / coreprof / coreprof.c
1 #include "runtime.h"
2 #include "coreprof.h"
3 #include <unistd.h>
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <fcntl.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include "mlp_lock.h"
10
11 __thread int                     cp_threadnum;
12 __thread struct coreprofmonitor* cp_monitor     = NULL;
13          struct coreprofmonitor* cp_monitorList = NULL;
14 static volatile int              cp_threadCount = 0;
15
16
17 static inline int atomicinc(volatile int *lock) {
18   int retval=1;
19   __asm__ __volatile__("lock; xadd %0,%1"
20                        : "=r"(retval)
21                        : "m"(*lock), "0"(retval)
22                        : "memory");
23   return retval;
24 }
25
26
27 // Need to have global lock before calling this method
28 void cp_create() {
29   if( cp_monitor != NULL )
30     return;
31
32   struct coreprofmonitor* monitor = 
33     calloc( 1, sizeof( struct coreprofmonitor ) );
34
35   if( monitor == NULL ) {
36     printf( "ERROR: calloc returned NULL\n" );
37     exit( -1 );
38   }
39
40   struct coreprofmonitor* tmp;
41
42   // add ourself to the list
43   do {
44     tmp           = cp_monitorList;
45     monitor->next = tmp;
46   } while( CAS( &cp_monitorList, 
47                 (INTPTR) tmp, 
48                 (INTPTR) monitor 
49                 ) != ((INTPTR)tmp)
50            );
51
52   int ourcount = atomicinc( &cp_threadCount );
53   cp_threadnum = ourcount;
54
55   // point thread lock variable to event monitor
56   cp_monitor = monitor;
57   CP_LOGEVENT( CP_EVENTID_MAIN, CP_EVENTTYPE_BEGIN );
58 }
59
60 // Place to do shutdown stuff
61 void cp_exit() {
62   CP_LOGEVENT( CP_EVENTID_MAIN, CP_EVENTTYPE_END );
63 }
64
65 void cp_writedata( int fd, char* buffer, int count ) {
66   int offset = 0;
67   while( count > 0 ) {
68     int size = write( fd, &buffer[offset], count );
69     offset += size;
70     count  -= size;
71   }
72 }
73
74
75 void cp_dump() {
76   
77   int fd = open( "coreprof.dat", O_RDWR | O_CREAT, S_IRWXU );
78   int numThreads = 0;
79   int i;
80
81   struct coreprofmonitor* monitor;
82
83   // WRITING HEADER
84
85   // Write version number
86   int version = 0;
87   cp_writedata( fd, 
88                 (char*)&version, 
89                 sizeof( int ) );
90
91   // Write the number of threads
92   monitor = cp_monitorList;
93   while( monitor != NULL ) {
94     numThreads++;
95     monitor = monitor->next;
96   }
97   cp_writedata( fd, 
98                 (char*)&numThreads, 
99                 sizeof( int ) );
100
101   // Write the number of words used to log
102   // events for each thread
103   monitor = cp_monitorList;
104   while( monitor != NULL ) {
105     cp_writedata( fd, 
106                   (char*)&monitor->numWords, 
107                   sizeof( int ) );
108     monitor = monitor->next;
109   }
110
111   // END HEADER, BEGIN DATA
112   monitor = cp_monitorList;
113   while( monitor != NULL ) {
114     cp_writedata( fd, 
115                   (char*)monitor->data, 
116                   sizeof( unsigned int )*monitor->numWords );
117     monitor = monitor->next;
118   }
119
120   close( fd );
121 }
122
123
124 void cp_reportOverflow() {
125   printf( "ERROR: coreprof event overflow\n" ); 
126   exit( -1 );
127 }