xref: /haiku/src/bin/ps.c (revision 2222d0559df303a9846a2fad53741f8b20b14d7c)
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  *		Bjoern Herzig (xRaich[o]2x)
9  */
10 #include <stdio.h>
11 #include <unistd.h>
12 #include <string.h>
13 
14 #include <OS.h>
15 
16 #define SNOOZE_TIME 100000
17 
18 char *sStates[] = {"run", "rdy", "msg", "zzz", "sus", "wait" };
19 
20 static void printTeamThreads(team_info *teamInfo, bool printSemaphoreInfo);
21 static void printTeamInfo(team_info *teamInfo, bool printHeader);
22 
23 static void
24 printTeamInfo(team_info *teamInfo, bool printHeader)
25 {
26 	// Print team info
27 	if (printHeader)
28 		printf("%-50s %5s %8s %4s %4s\n", "Team", "Id", "#Threads", "Gid", \
29 			"Uid");
30 
31 	printf("%-50s %5ld %8ld %4d %4d\n", teamInfo->args, teamInfo->team,
32 		teamInfo->thread_count, teamInfo->uid, teamInfo->gid);
33 }
34 
35 
36 static void
37 printTeamThreads(team_info *teamInfo, bool printSemaphoreInfo)
38 {
39 	char *threadState;
40 	uint32 threadCookie = 0;
41 	sem_info semaphoreInfo;
42 	thread_info threadInfo;
43 
44 	// Print all info about its threads too
45 	while (get_next_thread_info(teamInfo->team, &threadCookie, &threadInfo)
46 		>= B_OK) {
47 		if (threadInfo.state < B_THREAD_RUNNING
48 			|| threadInfo.state > B_THREAD_WAITING)
49 			// This should never happen
50 			threadState = "???";
51 		else
52 			threadState = sStates[threadInfo.state - 1];
53 
54 		printf("%-37s %5ld %8s %4ld %8llu %8llu ",
55 			threadInfo.name, threadInfo.thread, threadState,
56 			threadInfo.priority, (threadInfo.user_time / 1000),
57 			(threadInfo.kernel_time / 1000));
58 
59 		if (printSemaphoreInfo) {
60 			if (threadInfo.state == B_THREAD_WAITING && threadInfo.sem != -1) {
61 				status_t status = get_sem_info(threadInfo.sem, &semaphoreInfo);
62 				if (status == B_OK)
63 					printf("%s(%ld)\n", semaphoreInfo.name, semaphoreInfo.sem);
64 				else
65 					printf("%s(%ld)\n", strerror(status), threadInfo.sem);
66 			} else
67 				puts("");
68 		} else
69 			puts("");
70 	}
71 }
72 
73 int
74 main(int argc, char **argv)
75 {
76 	team_info teamInfo;
77 	uint32 teamCookie = 0;
78 	system_info systemInfo;
79 	bool printSystemInfo = false;
80 	bool printThreads = false;
81 	bool printHeader = true;
82 	bool printSemaphoreInfo = false;
83 	// match this in team name
84 	char *string_to_match;
85 
86 	int c;
87 
88 	while ((c = getopt(argc, argv,"ihas")) != EOF) {
89 		switch(c) {
90 			case 'i':
91 				printSystemInfo = true;
92 				break;
93 			case 'h':
94 				printf( "usage: ps [-hais] [team]\n"
95 			   			"-h : show help\n"
96 			   			"-i : show system info\n"
97 			   			"-s : show semaphore info\n"
98 			   			"-a : show threads too (by default only teams are " \
99 			   				"displayed)\n");
100 				return 0;
101 				break;
102 			case 'a':
103 				printThreads = true;
104 				break;
105 			case 's':
106 				printSemaphoreInfo = true;
107 				break;
108 		}
109 	}
110 
111 	// TODO: parse command line
112 	// Possible command line options:
113 	// 		-t	pstree like output
114 
115 	if (argc == 2 && (printSystemInfo||printThreads))
116 		string_to_match = NULL;
117 	else
118 		string_to_match = (argc >= 2) ? argv[argc-1] : NULL;
119 
120 	if (!string_to_match) {
121 		while (get_next_team_info(&teamCookie, &teamInfo) >= B_OK) {
122 
123 			printTeamInfo(&teamInfo,printHeader);
124 			printHeader = false;
125 			if (printThreads) {
126 				printf("\n%-37s %5s %8s %4s %8s %8s\n", "Thread", "Id", \
127 					"State", "Prio", "UTime", "KTime");
128 				printTeamThreads(&teamInfo,printSemaphoreInfo);
129 				printf("----------------------------------------------" \
130 					"-----------------------------\n");
131 				printHeader = true;
132 			}
133 		}
134 	} else {
135 		while (get_next_team_info(&teamCookie, &teamInfo) >= B_OK) {
136 			char *p;
137 			p = teamInfo.args;
138 			if ((p = strchr(p, ' ')))
139 				*p = '\0'; /* remove arguments, keep only argv[0] */
140 			p = strrchr(teamInfo.args, '/'); /* forget the path */
141 			if (p == NULL)
142 				p = teamInfo.args;
143 			if (strstr(p, string_to_match) == NULL)
144 				continue;
145 			printTeamInfo(&teamInfo,true);
146 			printf("\n%-37s %5s %8s %4s %8s %8s\n", "Thread", "Id", "State", \
147 				"Prio", "UTime", "KTime");
148 			printTeamThreads(&teamInfo,printSemaphoreInfo);
149 		}
150 	}
151 
152 	if (printSystemInfo) {
153 		// system stats
154 		get_system_info(&systemInfo);
155 		printf("\nSystem Info\n");
156 		printf("%luk (%lu bytes) total memory\n",
157 			(systemInfo.max_pages * B_PAGE_SIZE / 1024),
158 			(systemInfo.max_pages * B_PAGE_SIZE));
159 		printf("%luk (%lu bytes) currently committed\n",
160 			(systemInfo.used_pages * B_PAGE_SIZE / 1024),
161 			(systemInfo.used_pages * B_PAGE_SIZE));
162 		printf("%luk (%lu bytes) currently available\n",
163 			(systemInfo.max_pages - systemInfo.used_pages) * B_PAGE_SIZE / 1024,
164 			(systemInfo.max_pages - systemInfo.used_pages) * B_PAGE_SIZE);
165 		printf("%2.1f%% memory utilisation\n",
166 			(float)100 * systemInfo.used_pages / systemInfo.max_pages);
167 	}
168 	return 0;
169 }
170