1/* renice.c - unixish renice command for BeOs
2 * (c) 2001, 2002, Fran��ois Revol (mmu_man) for Haiku
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 Haiku,
9 *  Used the code to rewrite the 'prio' BeOS command for Haiku.
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
23From man renice:
24/usr/sbin/renice [-n increment] [-p] [-g | -u] ID ... /usr/sbin/renice priority [-p] pid ... [-g pgrp ...] [-u user ...]
25
26
27BeOs priorities:
28(realtime)	High Prio			Default					Low Prio
29120			99					10						1 (0 only for idle_thread)
30
31UNIX nice:
32			-20					0						19
33UNIX priorities:
34			0					20						39
35
36renice can be given more than one pid on the command line.
37prio is locked into one pid, then the priority.
38
39*/
40
41#ifndef NZERO
42#define NZERO 20
43#endif
44
45#define BZERO B_NORMAL_PRIORITY
46#define BMIN (B_REAL_TIME_DISPLAY_PRIORITY-1)
47//#define BMAX B_NORMAL_PRIORITY
48#define BMAX 1
49
50// returns an equivalent UNIX priority for a given BeOS priority.
51static int32 prio_be_to_unix(int32 prio)
52{
53	if (prio > BZERO)
54		return NZERO - ((prio - BZERO) * NZERO) / (BMIN - BZERO);
55	return NZERO + ((BZERO - prio) * (NZERO - 1)) / (BZERO - BMAX);
56}
57
58// returns an equivalent BeOS priority for a given UNIX priority.
59static int32 prio_unix_to_be(int32 prio)
60{
61	if (prio > NZERO)
62		return BZERO - ((prio - NZERO) * (BZERO - BMAX)) / (NZERO-1);
63	return BZERO + ((NZERO - prio) * (BMIN - BZERO)) / (NZERO);
64}
65
66static status_t renice_thread(int32 prio, int32 increment, bool use_be_prio, thread_id th)
67{
68	thread_info thinfo;
69
70	if(increment != 0) {
71		get_thread_info(th, &thinfo);
72		prio = thinfo.priority;
73		if(!use_be_prio)
74			prio = prio_be_to_unix(prio);
75		prio += increment;
76		if(!use_be_prio)
77			prio = prio_unix_to_be(prio);
78	}
79	return set_thread_priority(th, prio);
80}
81
82int main(int argc, char **argv)
83{
84	thread_id th = -1;
85	int32 prio, increment = 0;
86	thread_info thinfo;
87	bool use_be_prio = false;
88	bool next_is_prio = true;
89	bool next_is_increment = false;
90	bool use_increment = false;
91	bool find_by_name = false;
92	int i = 0;
93	int32 teamcookie = 0;
94	team_info teaminfo;
95	int32 thcookie = 0;
96	int err = 1;
97	char *thname;
98
99	prio = NZERO; // default UNIX priority for nice
100	// convert it to beos
101	if (!use_be_prio)
102	prio = prio_unix_to_be(prio);
103
104	while (++i < argc) {
105		if (!strcmp(argv[i], "-p")) { // ignored option
106		} else if (!strcmp(argv[i], "-n")) {
107			next_is_prio = false;
108			next_is_increment = true;
109			use_increment = true;
110		} else if (!strcmp(argv[i], "-b")) {
111			use_be_prio = true;
112		} else if (!strcmp(argv[i], "-f")) {
113			find_by_name = true;
114		} else if (next_is_increment) {
115			next_is_increment = false;
116			sscanf(argv[i], "%ld", (long *)&increment);
117		} else if (next_is_prio) {
118			next_is_prio = false;
119			sscanf(argv[i], "%ld", (long *)&prio);
120			if (!use_be_prio)
121				prio = prio_unix_to_be(prio);
122		} else {
123			if (!find_by_name) {
124			sscanf(argv[i], "%ld", (long *)&th);
125				return (renice_thread(prio, increment, use_be_prio, th) == B_OK)?0:1;
126			}
127			thname = argv[i];
128			while (get_next_team_info(&teamcookie, &teaminfo) == B_OK) {
129				thcookie = 0;
130				while (get_next_thread_info(teaminfo.team, &thcookie, &thinfo) == B_OK) {
131					if (!strncmp(thname, thinfo.name, B_OS_NAME_LENGTH)) {
132						th = thinfo.thread;
133						renice_thread(prio, increment, use_be_prio, th);
134						err = 0;
135						/* find another one */
136					}
137				}
138			}
139			return err;
140		}
141	}
142	if (th == -1) {
143		puts("Usage:");
144		puts("renice [-b] [-n increment | prio] [-f thname thname...|thid thid ...]");
145		puts("	-b : use BeOS priorities instead of UNIX priorities");
146		puts("	-n : adds increment to the current priority instead of assigning it");
147		puts("	-f : find threads by name instead of by id");
148		return 1;
149	}
150	return 0;
151}
152
153