? build ? install ? doc/Makefile.in ? tools/Makefile.in Index: tools/ev.c =================================================================== RCS file: /sources/fkt/FxT/tools/ev.c,v retrieving revision 1.13 diff -r1.13 ev.c 110c110 < evs->raw.end_data =evs->cur_pos + evs->fxt->infos.page_size; --- > evs->raw.end_data = evs->block.start + evs->block.ondisk.size; 265c265 < fprintf(stderr, "warning: %u arguments in trace (code %"PRIx64") whereas only room for %i\n", --- > fprintf(stderr, "warning: %u arguments in trace (code %"PRIx64") whereas only room for %i\n", Index: tools/fut-template.h =================================================================== RCS file: /sources/fkt/FxT/tools/fut-template.h,v retrieving revision 1.10 diff -r1.10 fut-template.h 285a286,288 > #define FUT_START_FLUSH_CODE 0xfff5 > #define FUT_STOP_FLUSH_CODE 0xfff4 > 310c313 < extern int fut_getbuffer( int *nints, unsigned long **buffer ); --- > extern int fut_getbuffer( int *nints, unsigned long **buffer, unsigned long *next_slot); Index: tools/fut_record.c =================================================================== RCS file: /sources/fkt/FxT/tools/fut_record.c,v retrieving revision 1.9 diff -r1.9 fut_record.c 10,11d9 < # else < # include 14a13,14 > #include > 183a184,185 > extern int allow_fut_flush; > extern pthread_mutex_t fut_flush_lock; 185,186c187,188 < unsigned long* fut_getstampedbuffer(unsigned long code, < int size) --- > unsigned long* __fut_record_event(fxt_trace_user_raw_t * rec, > unsigned long code) 188,204d189 < unsigned long *prev_slot, *next_slot; < < do { < prev_slot=(unsigned long *)fut_next_slot; < next_slot=(unsigned long*)((unsigned long)prev_slot+size); < } while (prev_slot != ma_cmpxchg(&fut_next_slot, < prev_slot, next_slot)); < < if (tbx_unlikely(next_slot > fut_last_slot)) { < fut_active=0; < /* Pourquoi on restaure ici ? Pas de race condition possible ? */ < fut_next_slot=prev_slot; < return trash_buffer; < } < < fxt_trace_user_raw_t *rec=(fxt_trace_user_raw_t *)prev_slot; < 236a222,268 > unsigned long* fut_getstampedbuffer(unsigned long code, > int size) > { > unsigned long *prev_slot, *next_slot; > retry: > do { > prev_slot=(unsigned long *)fut_next_slot; > next_slot=(unsigned long*)((unsigned long)prev_slot+size); > } while (prev_slot != ma_cmpxchg(&fut_next_slot, > prev_slot, next_slot)); > > > if (tbx_unlikely(next_slot > fut_last_slot)) { > if(allow_fut_flush) { > /* flush the buffer to disk */ > > if (prev_slot > fut_last_slot) > /* another thread is going to flush the buffer */ > goto retry; > > pthread_mutex_lock(&fut_flush_lock); > > if ((prev_slot + size > fut_last_slot) > && (prev_slot <= fut_last_slot)) { > > fut_flush(NULL, prev_slot, 1); > __fut_reset_pointers(); > fut_active = 1; > } > > pthread_mutex_unlock(&fut_flush_lock); > > goto retry; > } else { > /* stop recording events */ > fut_active=0; > /* Pourquoi on restaure ici ? Pas de race condition possible ? */ > fut_next_slot = prev_slot; > return trash_buffer; > } > } > > fxt_trace_user_raw_t *rec=(fxt_trace_user_raw_t *)prev_slot; > > return __fut_record_event(rec, code); > } > Index: tools/fut_setup.c =================================================================== RCS file: /sources/fkt/FxT/tools/fut_setup.c,v retrieving revision 1.3 diff -r1.3 fut_setup.c 31a32 > #include 69a71,103 > /* filename of the output trace */ > static char *fut_filename = NULL; > /* file descriptor of the output trace */ > static int fut_fd = 0; > > /* if !=0, activate the recording of thread id */ > int record_tid_activated = 0; > > /* if !=0, activate automatic buffer dumping: when the buffer is full, it is dumped to disk. > * This permits to record trace larger than the buffer, but this may kill the performance > */ > int allow_fut_flush = 0; > > pthread_mutex_t fut_flush_lock; > > static int already_flushed = 0; > > void fut_set_filename(char* filename) > { > if(fut_filename) { > if(already_flushed) > fprintf(stderr, "Warning: change output file name to %s, but some events have been saved in file %s\n", > filename, fut_filename); > free(fut_filename); > } > asprintf(&fut_filename, "%s", filename); > } > > void __fut_reset_pointers() > { > fut_next_slot = (unsigned long *)bufptr; > } > 82,83d115 < int record_tid_activated = 0; < 95a128,142 > /* activate automatic buffer dumping: when the buffer is full, it is dumped to disk. > * This permits to record trace larger than the buffer, but this may kill the performance > */ > void enable_fut_flush() > { > allow_fut_flush = 1; > } > > /* disactivate automatic buffer dumping > */ > void disable_fut_flush() > { > allow_fut_flush = 0; > } > 135c182 < --- > 163a211,214 > if(allow_fut_flush) { > pthread_mutex_init(&fut_flush_lock, NULL); > } > 208d258 < 216d265 < 269c318 < int fut_getbuffer( int *nlongs, unsigned long **buffer ) --- > int fut_getbuffer( int *nlongs, unsigned long **buffer, unsigned long *next_slot ) 284c333 < local_nlongs = ((char *)fut_next_slot - bufptr) / sizeof(long); --- > local_nlongs = ((char *)next_slot - bufptr) / sizeof(long); 296,305c345,346 < int fut_endup( char *filename ) < { < int n, nlongs=0, fd; < long size; < unsigned long *copy=NULL; < < /* stop all futher tracing */ < fut_active = 0; < < dumptime(&fut_infos->stop_time,&fut_infos->stop_jiffies); --- > int fut_flush( char* filename, void* next_slot, int record_flush_events ) > { 307,308c348,433 < if( (n = fut_getbuffer(&nlongs, ©)) < 0 ) < return n; --- > int n, nlongs=0; > long size; > unsigned long *copy=NULL; > static off_t begin = 0; > > dumptime(&fut_infos->stop_time,&fut_infos->stop_jiffies); > > if( (n = fut_getbuffer(&nlongs, ©, next_slot)) < 0 ) > return n; > > size = nlongs * sizeof(long); > > if(!fut_fd) { > > /* First time fut_flush is called. Open the output file and write headers */ > if( fut_filename == NULL ) > fut_filename = filename ; > > if( fut_filename == NULL ) > fut_filename = DEFAULT_TRACE_FILE; > > /* we can't open the file using the O_NONBLOCK option since after a call to write > * we are going to modify the buffer. If O_NONBLOCK is set, modifying the buffer while > * the OS is writting it may corrupt the output trace. > */ > > /* todo: implement a pipeline > * see Alexandre DENIS. "A High Performance Superpipeline Protocol for InfiniBand" in > * Proceedings of the 17th International Euro-Par Conference for instance > */ > if( (fut_fd = open(fut_filename, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0 ) > return fut_fd; > > already_flushed = 1; > /* write header */ > fxt_fdwrite(fut, fut_fd); > > /* begin a block of events */ > fxt_fdevents_start(fut, fut_fd, FXT_TRACE_USER_RAW); > > if( (begin=lseek(fut_fd,0,SEEK_CUR)) < 0 ) { > perror("getting block end seek"); > exit(EXIT_FAILURE); > } > > } > > fxt_trace_user_raw_t start_flush_event; > if(record_flush_events) > __fut_record_event(&start_flush_event, ((FUT_START_FLUSH_CODE)<<8) | 0x01); > > /* dump the buffer to disk */ > if( write(fut_fd, (void *)copy, size) < 0 ) { > perror("write buffer"); > } > > fxt_trace_user_raw_t stop_flush_event; > if(record_flush_events) { > __fut_record_event(&stop_flush_event, ((FUT_STOP_FLUSH_CODE)<<8) | 0x01); > > if( write(fut_fd, (void *)&start_flush_event, FUT_SIZE(0)) < 0 ) { > perror("write buffer"); > } > if( write(fut_fd, (void *)&stop_flush_event, FUT_SIZE(0)) < 0 ) { > perror("write buffer"); > } > } > > fut_infos->page_size = size; > > off_t end; > if( (end=lseek(fut_fd,0,SEEK_CUR)) < 0 ) { > perror("getting block end seek"); > exit(EXIT_FAILURE); > } > > /* Let's call fxt_fdevents_stop so that the data on disk is already correct. > * if the program crashes and can't manage to call fut_endup, the trace > * is still readable. > */ > fxt_fdevents_stop(fut, fut_fd); > > if( (lseek(fut_fd, end,SEEK_SET)) < 0 ) { > perror("getting block end seek"); > exit(EXIT_FAILURE); > } 310c435,436 < size = nlongs * sizeof(long); --- > return nlongs; > } 312,313c438,439 < if( filename == NULL ) < filename = DEFAULT_TRACE_FILE; --- > int fut_endup( char *filename ) > { 315,316c441,442 < if( (fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0 ) < return fd; --- > /* stop all futher tracing */ > fut_active = 0; 318,319c444,447 < fut_infos->page_size = size; < fxt_fdwrite(fut,fd); --- > /* dump the buffer to disk */ > int nlongs = fut_flush(filename, fut_next_slot, 0); > if(nlongs < 0) > return nlongs; 321,327c449,450 < fxt_fdevents_start(fut, fd, FXT_TRACE_USER_RAW); < //if( write(fd, (void *)&size, sizeof(size)) < sizeof(size) ) < // perror("write buffer's size"); < < if( write(fd, (void *)copy, size) < 0 ) < perror("write buffer"); < fxt_fdevents_stop(fut, fd); --- > /* end a block of events */ > fxt_fdevents_stop(fut, fut_fd); 329,330c452,453 < if( close(fd) < 0 ) < perror(filename); --- > if( close(fut_fd) < 0 ) > perror(fut_filename); 332c455,457 < //fut_done(); // Removed by Raymond --- > __fut_reset_pointers(); > //fut_done(); // Removed by Raymond > fut_active = 1; 334c459 < return nlongs; --- > return nlongs;