xref: /haiku/src/bin/ps.c (revision 4f2fd49bdc6078128b1391191e4edac647044c3d)
1 /*
2  * Copyright 2002-2008, Haiku Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Francois Revol (mmu_man)
7  *		Salvatore Benedetto <salvatore.benedetto@gmail.com>
8  */
9 #include <stdio.h>
10 #include <string.h>
11 
12 #include <OS.h>
13 
14 #define SNOOZE_TIME 100000
15 
16 
17 int
18 main(int argc, char **argv)
19 {
20 	team_info teamInfo;
21 	thread_info threadInfo;
22 	uint32 teamCookie = 0;
23 	uint32 threadCookie = 0;
24 	sem_info semaphoreInfo;
25 	char *threadState;
26 	char *states[] = {"run", "rdy", "msg", "zzz", "sus", "wait" };
27 	system_info systemInfo;
28 	bool printSystemInfo = true;
29 	// match this in team name
30 	char *string_to_match;
31 
32 	// TODO: parse command line
33 	// Possible command line options:
34 	// 		-h	show help
35 	// 			ps			- by default it only shows all team info
36 	// 			ps [team]	- shows info about this team with all its threads
37 	// 		-t	pstree like output
38 	// 		-a	show threads too (by default only teams are displayed)
39 	// 		-s	show semaphore info
40 	// 		-i	show system info
41 	string_to_match = (argc == 2) ? argv[1] : NULL;
42 
43 	printf("%-50s %4s %8s %4s %4s\n", "Team", "Id", "#Threads", "Gid", "Uid");
44 	while (get_next_team_info(&teamCookie, &teamInfo) >= B_OK) {
45 		if (string_to_match) {
46 			char *p;
47 			p = teamInfo.args;
48 			if ((p = strchr(p, ' ')))
49 				*p = '\0'; /* remove arguments, keep only argv[0] */
50 			p = strrchr(teamInfo.args, '/'); /* forget the path */
51 			if (p == NULL)
52 				p = teamInfo.args;
53 			if (strstr(p, string_to_match) == NULL)
54 				continue;
55 			// Print team info
56 			printf("%-50s %4ld %8ld %4d %4d\n\n", teamInfo.args, teamInfo.team,
57 				teamInfo.thread_count, teamInfo.uid, teamInfo.gid);
58 
59 			printf("%-30s %4s %8s %4s %8s %8s\n", "Thread", "Id", "State",
60 				"Prio", "UTime", "KTime");
61 			// Print all info about its threads too
62 			while (get_next_thread_info(teamInfo.team, &threadCookie, &threadInfo)
63 				>= B_OK) {
64 				if (threadInfo.state < B_THREAD_RUNNING
65 					|| threadInfo.state > B_THREAD_WAITING)
66 					// This should never happen
67 					threadState = "???";
68 				else
69 					threadState = states[threadInfo.state - 1];
70 
71 				printf("%-30s %4ld %8s %4ld %8llu %8llu ",
72 					threadInfo.name, threadInfo.thread, threadState,
73 					threadInfo.priority, (threadInfo.user_time / 1000),
74 					(threadInfo.kernel_time / 1000));
75 
76 				if (threadInfo.state == B_THREAD_WAITING && threadInfo.sem != -1) {
77 					status_t status = get_sem_info(threadInfo.sem, &semaphoreInfo);
78 					if (status == B_OK)
79 						printf("%s(%ld)\n", semaphoreInfo.name, semaphoreInfo.sem);
80 					else
81 						printf("%s(%ld)\n", strerror(status), threadInfo.sem);
82 				} else
83 					puts("");
84 			}
85 			break;
86 
87 		} else {
88 			printf("%-50s %4ld %8ld %4d %4d\n", teamInfo.args, teamInfo.team,
89 				teamInfo.thread_count, teamInfo.uid, teamInfo.gid);
90 		}
91 	}
92 
93 	if (printSystemInfo) {
94 		// system stats
95 		get_system_info(&systemInfo);
96 		printf("\nSystem Info\n");
97 		printf("%luk (%lu bytes) total memory\n",
98 			(systemInfo.max_pages * B_PAGE_SIZE / 1024),
99 			(systemInfo.max_pages * B_PAGE_SIZE));
100 		printf("%luk (%lu bytes) currently committed\n",
101 			(systemInfo.used_pages * B_PAGE_SIZE / 1024),
102 			(systemInfo.used_pages * B_PAGE_SIZE));
103 		printf("%luk (%lu bytes) currently available\n",
104 			(systemInfo.max_pages - systemInfo.used_pages) * B_PAGE_SIZE / 1024,
105 			(systemInfo.max_pages - systemInfo.used_pages) * B_PAGE_SIZE);
106 		printf("%2.1f%% memory utilisation\n",
107 			(float)100 * systemInfo.used_pages / systemInfo.max_pages);
108 	}
109 	return 0;
110 }
111