xref: /haiku/src/bin/ps.c (revision e85e399fd7b229b8bc92f28928a059876d7216d3)
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 %5" B_PRId32 " %8" B_PRId32 " %4d %4d\n", teamInfo->args,
32 		teamInfo->team, teamInfo->thread_count, teamInfo->gid, teamInfo->uid);
33 }
34 
35 
36 static void
37 printTeamThreads(team_info *teamInfo, bool printSemaphoreInfo)
38 {
39 	char *threadState;
40 	int32 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 %5" B_PRId32 " %8s %4" B_PRId32 " %8" B_PRIu64 " %8"
55 			B_PRId64 " ", 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(%" B_PRId32 ")\n", semaphoreInfo.name,
64 						semaphoreInfo.sem);
65 				} else {
66 					printf("%s(%" B_PRId32 ")\n", strerror(status),
67 						threadInfo.sem);
68 				}
69 			} else
70 				puts("");
71 		} else
72 			puts("");
73 	}
74 }
75 
76 int
77 main(int argc, char **argv)
78 {
79 	team_info teamInfo;
80 	int32 teamCookie = 0;
81 	system_info systemInfo;
82 	bool printSystemInfo = false;
83 	bool printThreads = false;
84 	bool printHeader = true;
85 	bool printSemaphoreInfo = false;
86 	// match this in team name
87 	char *string_to_match;
88 
89 	int c;
90 
91 	while ((c = getopt(argc, argv,"ihas")) != EOF) {
92 		switch(c) {
93 			case 'i':
94 				printSystemInfo = true;
95 				break;
96 			case 'h':
97 				printf( "usage: ps [-hais] [team]\n"
98 			   			"-h : show help\n"
99 			   			"-i : show system info\n"
100 			   			"-s : show semaphore info\n"
101 			   			"-a : show threads too (by default only teams are " \
102 			   				"displayed)\n");
103 				return 0;
104 				break;
105 			case 'a':
106 				printThreads = true;
107 				break;
108 			case 's':
109 				printSemaphoreInfo = true;
110 				break;
111 		}
112 	}
113 
114 	// TODO: parse command line
115 	// Possible command line options:
116 	// 		-t	pstree like output
117 
118 	if (argc == 2 && (printSystemInfo||printThreads))
119 		string_to_match = NULL;
120 	else
121 		string_to_match = (argc >= 2) ? argv[argc-1] : NULL;
122 
123 	if (!string_to_match) {
124 		while (get_next_team_info(&teamCookie, &teamInfo) >= B_OK) {
125 
126 			printTeamInfo(&teamInfo,printHeader);
127 			printHeader = false;
128 			if (printThreads) {
129 				printf("\n%-37s %5s %8s %4s %8s %8s\n", "Thread", "Id", \
130 					"State", "Prio", "UTime", "KTime");
131 				printTeamThreads(&teamInfo,printSemaphoreInfo);
132 				printf("----------------------------------------------" \
133 					"-----------------------------\n");
134 				printHeader = true;
135 			}
136 		}
137 	} else {
138 		while (get_next_team_info(&teamCookie, &teamInfo) >= B_OK) {
139 			char *p;
140 			p = teamInfo.args;
141 			if ((p = strchr(p, ' ')))
142 				*p = '\0'; /* remove arguments, keep only argv[0] */
143 			p = strrchr(teamInfo.args, '/'); /* forget the path */
144 			if (p == NULL)
145 				p = teamInfo.args;
146 			if (strstr(p, string_to_match) == NULL)
147 				continue;
148 			printTeamInfo(&teamInfo,true);
149 			printf("\n%-37s %5s %8s %4s %8s %8s\n", "Thread", "Id", "State", \
150 				"Prio", "UTime", "KTime");
151 			printTeamThreads(&teamInfo,printSemaphoreInfo);
152 		}
153 	}
154 
155 	if (printSystemInfo) {
156 		// system stats
157 		get_system_info(&systemInfo);
158 		printf("\nSystem Info\n");
159 		printf("%" B_PRIu32 "k (%" B_PRIu32 " bytes) total memory\n",
160 			(systemInfo.max_pages * B_PAGE_SIZE / 1024),
161 			(systemInfo.max_pages * B_PAGE_SIZE));
162 		printf("%" B_PRIu32 "k (%" B_PRIu32 " bytes) currently committed\n",
163 			(systemInfo.used_pages * B_PAGE_SIZE / 1024),
164 			(systemInfo.used_pages * B_PAGE_SIZE));
165 		printf("%" B_PRIu32 "k (%" B_PRIu32 " bytes) currently available\n",
166 			(systemInfo.max_pages - systemInfo.used_pages) * B_PAGE_SIZE / 1024,
167 			(systemInfo.max_pages - systemInfo.used_pages) * B_PAGE_SIZE);
168 		printf("%2.1f%% memory utilisation\n",
169 			(float)100 * systemInfo.used_pages / systemInfo.max_pages);
170 	}
171 	return 0;
172 }
173