a21e856ded04d7ebe71fcb5ad01bbc384fc84e7b
[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   struct coreprofmonitor* tmp;
36
37   // add ourself to the list
38   do {
39     tmp           = cp_monitorList;
40     monitor->next = tmp;
41   } while( CAS( &cp_monitorList, 
42                 (INTPTR) tmp, 
43                 (INTPTR) monitor 
44                 ) != ((INTPTR)tmp)
45            );
46
47   int ourcount = atomicinc( &cp_threadCount );
48   cp_threadnum = ourcount;
49
50   // point thread lock variable to event monitor
51   cp_monitor = monitor;
52   CP_LOGEVENT( CP_EVENTID_MAIN, CP_EVENTTYPE_BEGIN );
53 }
54
55 // Place to do shutdown stuff
56 void cp_exit() {
57   CP_LOGEVENT( CP_EVENTID_MAIN, CP_EVENTTYPE_END );
58 }
59
60 void cp_writedata( int fd, char* buffer, int count ) {
61   int offset = 0;
62   while( count > 0 ) {
63     int size = write( fd, &buffer[offset], count );
64     offset += size;
65     count  -= size;
66   }
67 }
68
69
70 void cp_dump() {
71   
72   //int fdh   = open( "coreprof-head.dat", O_RDWR | O_CREAT, S_IRWXU );
73   //int fde   = open( "coreprof-evnt.dat", O_RDWR | O_CREAT, S_IRWXU );
74   //int fdt   = open( "coreprof-time.dat", O_RDWR | O_CREAT, S_IRWXU );
75   int fd    = open( "coreprof.dat", O_RDWR | O_CREAT, S_IRWXU );
76   int count = 0;
77   int i;
78
79   struct coreprofmonitor* monitor;
80
81   // WRITING HEADER
82
83   // Write version number
84   int version = 0;
85   cp_writedata( fd, 
86                 (char*)&version, 
87                 sizeof( int ) );
88
89   // check for overflow
90   monitor = cp_monitorList;
91   while( monitor != NULL ) {
92     count++;
93     if( monitor->numEvents > CP_MAXEVENTS ) {
94       printf( "ERROR: EVENT COUNT EXCEEDED\n" );
95     }
96     monitor = monitor->next;
97   }
98
99   // Write the number of threads
100   cp_writedata( fd, 
101                 (char*)&count, 
102                 sizeof( int ) );
103
104   monitor = cp_monitorList;
105   while( monitor != NULL ) {
106
107     // Write the number of events for each thread
108     cp_writedata( fd, 
109                   (char*)&monitor->numEvents, 
110                   sizeof( int ) );
111
112     monitor = monitor->next;
113   }
114
115   // END HEADER, BEGIN DATA
116
117   monitor = cp_monitorList;
118   while( monitor != NULL ) {
119
120     // Write the event IDs (index matches time below)
121     cp_writedata( fd, 
122                   (char*)monitor->events, 
123                   sizeof( unsigned int )*monitor->numEvents );
124
125     // Write the event timestamps (index matches above)
126     cp_writedata( fd, 
127                   (char*)monitor->logTimes_ms, 
128                   sizeof( long long )*monitor->numEvents );
129     monitor = monitor->next;
130   }
131
132   close( fd );
133   //close( fde );
134   //close( fdt );
135 }
136
137
138 void cp_reportOverflow() {
139   printf( "ERROR: coreprof event overflow\n" ); 
140   exit( -1 );
141 }