mirror of
https://github.com/FeralInteractive/gamemode.git
synced 2025-06-26 17:31:45 +02:00
Set up for resetting niceness value
Add tests to check this feature Apply config validation in config for simplicity Note: if anything messes with the niceness (ie. it starts non-zero, or it's not the expected value during setup, we'll bail out)
This commit is contained in:
@ -54,13 +54,28 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
* This tries to change the scheduler of the client to soft realtime mode
|
||||
* available in some kernels as SCHED_ISO. It also tries to adjust the nice
|
||||
* level. If some of each fail, ignore this and log a warning.
|
||||
*
|
||||
* We don't need to store the current values because when the client exits,
|
||||
* everything will be good: Scheduling is only applied to the client and
|
||||
* its children.
|
||||
*/
|
||||
void game_mode_apply_renice(const GameModeContext *self, const pid_t client)
|
||||
|
||||
#define RENICE_INVALID -128 /* Special value to store invalid value */
|
||||
int game_mode_get_renice(const pid_t client)
|
||||
{
|
||||
/* Clear errno as -1 is a regitimate return */
|
||||
errno = 0;
|
||||
int priority = getpriority(PRIO_PROCESS, (id_t)client);
|
||||
if (priority == -1 && errno) {
|
||||
LOG_ERROR("getprority(PRIO_PROCESS, %d) failed : %s\n", client, strerror(errno));
|
||||
return RENICE_INVALID;
|
||||
}
|
||||
return -priority;
|
||||
}
|
||||
|
||||
/* If expected is 0 then we try to apply our renice, otherwise, we try to remove it */
|
||||
void game_mode_apply_renice(const GameModeContext *self, const pid_t client, int expected)
|
||||
{
|
||||
if (expected == RENICE_INVALID)
|
||||
/* Silently bail if fed an invalid value */
|
||||
return;
|
||||
|
||||
GameModeConfig *config = game_mode_config_from_context(self);
|
||||
|
||||
/*
|
||||
@ -69,18 +84,35 @@ void game_mode_apply_renice(const GameModeContext *self, const pid_t client)
|
||||
long int renice = config_get_renice_value(config);
|
||||
if (renice == 0) {
|
||||
return;
|
||||
} else if ((renice < 1) || (renice > 20)) {
|
||||
LOG_ONCE(ERROR, "Configured renice value '%ld' is invalid, will not renice.\n", renice);
|
||||
return;
|
||||
} else {
|
||||
renice = -renice;
|
||||
}
|
||||
|
||||
/*
|
||||
* don't adjust priority if it was already adjusted
|
||||
*/
|
||||
if (getpriority(PRIO_PROCESS, (id_t)client) != 0) {
|
||||
LOG_ERROR("Refused to renice client [%d]: already reniced\n", client);
|
||||
/* Invert the renice value */
|
||||
renice = -renice;
|
||||
|
||||
/* When expected is non-zero, we should try and remove the renice only if it doesn't match the
|
||||
* expected value */
|
||||
if (expected != 0) {
|
||||
expected = (int)renice;
|
||||
renice = 0;
|
||||
}
|
||||
|
||||
/* Clear errno as -1 is a regitimate return */
|
||||
errno = 0;
|
||||
int prio = getpriority(PRIO_PROCESS, (id_t)client);
|
||||
if (prio == -1 && errno) {
|
||||
/* process has likely ended, only log an error if we were actually trying to set a non-zero
|
||||
* value */
|
||||
if (errno == ESRCH && renice != 0)
|
||||
LOG_ERROR("getpriority returned ESRCH for process %d\n", client);
|
||||
} else if (prio != expected) {
|
||||
/*
|
||||
* Don't adjust priority if it does not match the expected value
|
||||
* ie. Another process has changed it, or it began non-standard
|
||||
*/
|
||||
LOG_ERROR("Refused to renice client [%d]: prio was (%d) but we expected (%d)\n",
|
||||
client,
|
||||
prio,
|
||||
expected);
|
||||
} else if (setpriority(PRIO_PROCESS, (id_t)client, (int)renice)) {
|
||||
LOG_HINTED(ERROR,
|
||||
"Failed to renice client [%d], ignoring error condition: %s\n",
|
||||
|
Reference in New Issue
Block a user