xref: /haiku/src/bin/renice.c (revision cda5b8808fd0262f0fac472f6cfa809f846a83cf)
1 /* renice.c - unixish renice command for BeOs
2  * (c) 2001, 2002, Fran�ois Revol (mmu_man) for OpenBeOS
3  * released under the MIT licence.
4  *
5  * How did I live without it before ??? ;)
6  * ChangeLog:
7  * 04-25-2002 v1.2
8  *  Cleanup for inclusion in OpenBeOS,
9  *  Used the code to rewrite the 'prio' BeOS command for OpenBeOS.
10  * 04-14-2002 v1.1
11  *  Added -f upon suggestion from Id�fix on BeShare
12  * 2001 v1.0
13  *  Initial.
14  */
15 
16 #include <OS.h>
17 #include <stdio.h>
18 #include <string.h>
19 
20 /*
21    Notes:
22 
23 From man renice:
24 /usr/sbin/renice [-n increment] [-p] [-g | -u] ID ... /usr/sbin/renice priority [-p] pid ... [-g pgrp ...] [-u user ...]
25 
26 
27 #define B_LOW_PRIORITY                  5
28 #define B_NORMAL_PRIORITY               10
29 #define B_DISPLAY_PRIORITY              15
30 #define B_URGENT_DISPLAY_PRIORITY       20
31 #define B_REAL_TIME_DISPLAY_PRIORITY    100
32 #define B_URGENT_PRIORITY               110
33 #define B_REAL_TIME_PRIORITY            120
34 
35 BeOs priorities:
36 High Prio (realtime)            Default                  Low Prio
37 120                               10                        1 (0 only for idle_thread)
38 
39 UNIX Priorities:
40 -20                               0                         20
41 
42 Note that however this isn't perfect, since priorities
43 beyond 100 in BeOS move the thread into the real-time class.
44 Linux for example, has a separate API for doing this,
45 and even a process set to -20 can be in the normal scheduling class.
46 
47 renice can be given more than one pid on the command line.
48 prio is locked into one pid, then the priority.
49 
50 */
51 
52 // returns an equivalent UNIX priority for a given BeOS priority.
53 static int32 prio_be_to_unix(int32 prio)
54 {
55 	return (prio > 10)?(- (20 * (prio - 10)) / 110):(2 * (10 - prio));
56 }
57 
58 // returns an equivalent BeOS priority for a given UNIX priority.
59 static int32 prio_unix_to_be(int32 prio)
60 {
61 	return (prio > 0)?(10 - (prio/2)):(10 + 110 * (-prio) / 20);
62 }
63 
64 static status_t renice_thread(int32 prio, int32 increment, bool use_be_prio, thread_id th)
65 {
66 	thread_info thinfo;
67 
68 	if(increment != 0) {
69 		get_thread_info(th, &thinfo);
70 		prio = thinfo.priority;
71 		if(!use_be_prio)
72 			prio = prio_be_to_unix(prio);
73 		prio += increment;
74 		if(!use_be_prio)
75 			prio = prio_unix_to_be(prio);
76 	}
77 	return set_thread_priority(th, prio);
78 }
79 
80 int main(int argc, char **argv)
81 {
82 	thread_id th = -1;
83 	int32 prio, increment = 0;
84 	thread_info thinfo;
85 	bool use_be_prio = false;
86 	bool next_is_prio = true;
87 	bool next_is_increment = false;
88 	bool use_increment = false;
89 	bool find_by_name = false;
90 	int i = 0;
91 	int32 teamcookie = 0;
92 	team_info teaminfo;
93 	int32 thcookie = 0;
94 	int err = 1;
95 	char *thname;
96 
97 	prio = 9; // default UNIX priority for nice
98 	// convert it to beos
99 	if (!use_be_prio)
100 	prio = prio_unix_to_be(prio);
101 
102 	while (++i < argc) {
103 		if (!strcmp(argv[i], "-p")) { // ignored option
104 		} else if (!strcmp(argv[i], "-n")) {
105 			next_is_prio = false;
106 			next_is_increment = true;
107 			use_increment = true;
108 		} else if (!strcmp(argv[i], "-b")) {
109 			use_be_prio = true;
110 		} else if (!strcmp(argv[i], "-f")) {
111 			find_by_name = true;
112 		} else if (next_is_increment) {
113 			next_is_increment = false;
114 			sscanf(argv[i], "%ld", (long *)&increment);
115 		} else if (next_is_prio) {
116 			next_is_prio = false;
117 			sscanf(argv[i], "%ld", (long *)&prio);
118 			if (!use_be_prio)
119 				prio = prio_unix_to_be(prio);
120 		} else {
121 			if (!find_by_name) {
122 			sscanf(argv[i], "%ld", (long *)&th);
123 				return (renice_thread(prio, increment, use_be_prio, th) == B_OK)?0:1;
124 			}
125 			thname = argv[i];
126 			while (get_next_team_info(&teamcookie, &teaminfo) == B_OK) {
127 				thcookie = 0;
128 				while (get_next_thread_info(teaminfo.team, &thcookie, &thinfo) == B_OK) {
129 					if (!strncmp(thname, thinfo.name, B_OS_NAME_LENGTH)) {
130 						th = thinfo.thread;
131 						renice_thread(prio, increment, use_be_prio, th);
132 						err = 0;
133 					}
134 				}
135 			}
136 			return err;
137 		}
138 	}
139 	if (th == -1) {
140 		puts("Usage:");
141 		puts("renice [-b] [-n increment | prio] [-f thname thname...|thid thid ...]");
142 		puts("	-b : use BeOS priorities instead of UNIX priorities");
143 		puts("	-n : adds increment to the current priority instead of assigning it");
144 		puts("	-f : find threads by name instead of by id");
145 		return 1;
146 	}
147 	return 0;
148 }
149 
150