xref: /haiku/src/bin/debug/time_stats/time_stats.cpp (revision 44521466280be8d8f1e91bb0bdf7bd65c1375e90)
13c3d2b85SIngo Weinhold /*
23c3d2b85SIngo Weinhold  * Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
33c3d2b85SIngo Weinhold  * Distributed under the terms of the MIT License.
43c3d2b85SIngo Weinhold  */
53c3d2b85SIngo Weinhold 
63c3d2b85SIngo Weinhold #include <errno.h>
73c3d2b85SIngo Weinhold #include <fcntl.h>
83c3d2b85SIngo Weinhold #include <getopt.h>
93c3d2b85SIngo Weinhold #include <stdio.h>
103c3d2b85SIngo Weinhold #include <stdlib.h>
113c3d2b85SIngo Weinhold #include <string.h>
123c3d2b85SIngo Weinhold #include <sys/stat.h>
133c3d2b85SIngo Weinhold #include <unistd.h>
143c3d2b85SIngo Weinhold 
153c3d2b85SIngo Weinhold #include <OS.h>
163c3d2b85SIngo Weinhold 
17*44521466SIngo Weinhold #include "time_stats.h"
183c3d2b85SIngo Weinhold 
193c3d2b85SIngo Weinhold 
203c3d2b85SIngo Weinhold #define SCHEDULING_ANALYSIS_BUFFER_SIZE	10 * 1024 * 1024
213c3d2b85SIngo Weinhold 
223c3d2b85SIngo Weinhold 
233c3d2b85SIngo Weinhold extern const char* __progname;
243c3d2b85SIngo Weinhold 
253c3d2b85SIngo Weinhold static const char* kUsage =
263c3d2b85SIngo Weinhold 	"Usage: %s [ <options> ] <command line>\n"
273c3d2b85SIngo Weinhold 	"Executes the given command line <command line> and print an analysis of\n"
283c3d2b85SIngo Weinhold 	"the user and kernel times of all threads that ran during that time.\n"
293c3d2b85SIngo Weinhold 	"\n"
303c3d2b85SIngo Weinhold 	"Options:\n"
313c3d2b85SIngo Weinhold 	"  -b <size>    - When doing scheduling analysis: the size of the buffer\n"
323c3d2b85SIngo Weinhold 	"                 used (in MB)\n"
333c3d2b85SIngo Weinhold 	"  -h, --help   - Print this usage info.\n"
343c3d2b85SIngo Weinhold 	"  -o <output>  - Print the results to file <output>.\n"
353c3d2b85SIngo Weinhold 	"  -s           - Also perform a scheduling analysis over the time the\n"
363c3d2b85SIngo Weinhold 	"                 child process ran. This requires that scheduler kernel\n"
373c3d2b85SIngo Weinhold 	"                 tracing had been enabled at compile time.\n"
383c3d2b85SIngo Weinhold ;
393c3d2b85SIngo Weinhold 
403c3d2b85SIngo Weinhold 
413c3d2b85SIngo Weinhold static void
print_usage_and_exit(bool error)423c3d2b85SIngo Weinhold print_usage_and_exit(bool error)
433c3d2b85SIngo Weinhold {
443c3d2b85SIngo Weinhold     fprintf(error ? stderr : stdout, kUsage, __progname);
453c3d2b85SIngo Weinhold     exit(error ? 1 : 0);
463c3d2b85SIngo Weinhold }
473c3d2b85SIngo Weinhold 
483c3d2b85SIngo Weinhold 
493c3d2b85SIngo Weinhold int
main(int argc,const char * const * argv)503c3d2b85SIngo Weinhold main(int argc, const char* const* argv)
513c3d2b85SIngo Weinhold {
523c3d2b85SIngo Weinhold 	const char* outputFile = NULL;
533c3d2b85SIngo Weinhold 	bool schedulingAnalysis = false;
543c3d2b85SIngo Weinhold 	size_t bufferSize = SCHEDULING_ANALYSIS_BUFFER_SIZE;
553c3d2b85SIngo Weinhold 
563c3d2b85SIngo Weinhold 	while (true) {
573c3d2b85SIngo Weinhold 		static struct option sLongOptions[] = {
583c3d2b85SIngo Weinhold 			{ "help", no_argument, 0, 'h' },
593c3d2b85SIngo Weinhold 			{ "output", required_argument, 0, 'o' },
603c3d2b85SIngo Weinhold 			{ 0, 0, 0, 0 }
613c3d2b85SIngo Weinhold 		};
623c3d2b85SIngo Weinhold 
633c3d2b85SIngo Weinhold 		opterr = 0; // don't print errors
643c3d2b85SIngo Weinhold 		int c = getopt_long(argc, (char**)argv, "+b:ho:s", sLongOptions, NULL);
653c3d2b85SIngo Weinhold 		if (c == -1)
663c3d2b85SIngo Weinhold 			break;
673c3d2b85SIngo Weinhold 
683c3d2b85SIngo Weinhold 		switch (c) {
693c3d2b85SIngo Weinhold 			case 'b':
703c3d2b85SIngo Weinhold 				bufferSize = atol(optarg);
713c3d2b85SIngo Weinhold 				if (bufferSize < 1 || bufferSize > 1024) {
723c3d2b85SIngo Weinhold 					fprintf(stderr, "Error: Invalid buffer size. Should be "
733c3d2b85SIngo Weinhold 						"between 1 and 1024 MB\n");
743c3d2b85SIngo Weinhold 					exit(1);
753c3d2b85SIngo Weinhold 				}
763c3d2b85SIngo Weinhold 				bufferSize *= 1024 * 1024;
773c3d2b85SIngo Weinhold 				break;
783c3d2b85SIngo Weinhold 			case 'h':
793c3d2b85SIngo Weinhold 				print_usage_and_exit(false);
803c3d2b85SIngo Weinhold 				break;
813c3d2b85SIngo Weinhold 			case 'o':
823c3d2b85SIngo Weinhold 				outputFile = optarg;
833c3d2b85SIngo Weinhold 				break;
843c3d2b85SIngo Weinhold 			case 's':
853c3d2b85SIngo Weinhold 				schedulingAnalysis = true;
863c3d2b85SIngo Weinhold 				break;
873c3d2b85SIngo Weinhold 
883c3d2b85SIngo Weinhold 			default:
893c3d2b85SIngo Weinhold 				print_usage_and_exit(true);
903c3d2b85SIngo Weinhold 				break;
913c3d2b85SIngo Weinhold 		}
923c3d2b85SIngo Weinhold 	}
933c3d2b85SIngo Weinhold 
943c3d2b85SIngo Weinhold 	if (optind >= argc)
953c3d2b85SIngo Weinhold 		print_usage_and_exit(true);
963c3d2b85SIngo Weinhold 
973c3d2b85SIngo Weinhold 	// open output file, if specified
983c3d2b85SIngo Weinhold 	int outFD = -1;
993c3d2b85SIngo Weinhold 	if (outputFile != NULL) {
1003c3d2b85SIngo Weinhold 		outFD = open(outputFile, O_WRONLY | O_CREAT | O_TRUNC,
1013c3d2b85SIngo Weinhold 			S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH | S_IWOTH);
1023c3d2b85SIngo Weinhold 		if (outFD < 0) {
1033c3d2b85SIngo Weinhold 			fprintf(stderr, "Error: Failed to open \"%s\": %s\n", outputFile,
1043c3d2b85SIngo Weinhold 				strerror(errno));
1053c3d2b85SIngo Weinhold 			exit(1);
1063c3d2b85SIngo Weinhold 		}
1073c3d2b85SIngo Weinhold 	}
1083c3d2b85SIngo Weinhold 
1093c3d2b85SIngo Weinhold 	do_timing_analysis(argc - optind, argv + optind, schedulingAnalysis, outFD,
1103c3d2b85SIngo Weinhold 		bufferSize);
1113c3d2b85SIngo Weinhold 
1123c3d2b85SIngo Weinhold 	return 0;
1133c3d2b85SIngo Weinhold }
114