alsactl: add --nice and --sched-idle options

The state management can run at low priority, add --nice and --sched-idle
options to set the scheduler.

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
Jaroslav Kysela 2013-04-10 09:42:40 +02:00
parent e2eab09c1d
commit 611249ae26
4 changed files with 49 additions and 3 deletions

View file

@ -8,7 +8,7 @@ endif
EXTRA_DIST=alsactl.1 alsactl_init.xml
alsactl_SOURCES=alsactl.c state.c lock.c utils.c init_parse.c daemon.c
alsactl_CFLAGS=$(AM_CFLAGS) -DSYS_ASOUNDRC=\"$(ASOUND_STATE_DIR)/asound.state\" -DSYS_PIDFILE=\"$(ALSACTL_PIDFILE_DIR)/alsactl.pid\"
alsactl_CFLAGS=$(AM_CFLAGS) -D__USE_GNU -DSYS_ASOUNDRC=\"$(ASOUND_STATE_DIR)/asound.state\" -DSYS_PIDFILE=\"$(ALSACTL_PIDFILE_DIR)/alsactl.pid\"
noinst_HEADERS=alsactl.h list.h init_sysdeps.c init_utils_string.c init_utils_run.c init_sysfs.c
dist_udevrules_DATA = \

View file

@ -7,5 +7,5 @@ Conflicts=shutdown.target
[Service]
Type=simple
ExecStart=-@sbindir@/alsactl -s rdaemon
ExecStart=-@sbindir@/alsactl -s -n 19 -c rdaemon
ExecStop=-@sbindir@/alsactl -s rkill save_and_quit

View file

@ -115,6 +115,14 @@ Run the task in background.
\fI\-s, \-\-syslog\fP
Use syslog for messages.
.TP
\fI\-n, \-\-nice\fP
Set the process priority (see 'man nice')
.TP
\fI\-c, \-\-sched-idle\fP
Set the process scheduling policy to idle (SCHED_IDLE).
.SH FILES
\fI/var/lib/alsa/asound.state\fP (or whatever file you specify with the
\fB\-f\fP flag) is used to store current settings for your

View file

@ -28,6 +28,7 @@
#include <assert.h>
#include <errno.h>
#include <syslog.h>
#include <sched.h>
#include <alsa/asoundlib.h>
#include "alsactl.h"
@ -87,6 +88,8 @@ static struct arg args[] = {
{ 0, NULL, " (default " DATADIR "/init/00main)" },
{ 'b', "background", "run daemon in background" },
{ 's', "syslog", "use syslog for messages" },
{ INTARG | 'n', "nice", "set the process priority (see 'man nice')" },
{ 'c', "sched-idle", "set the process scheduling policy to idle (SCHED_IDLE)" },
{ HEADER, NULL, "Available commands:" },
{ CARDCMD, "store", "save current driver setup for one or each soundcards" },
{ EMPCMD, NULL, " to configuration file" },
@ -140,6 +143,25 @@ static void help(void)
}
}
#define NO_NICE (-100000)
static void do_nice(int use_nice, int sched_idle)
{
struct sched_param sched_param;
if (use_nice != NO_NICE && nice(use_nice) < 0)
error("nice(%i): %s", use_nice, strerror(errno));
if (sched_idle) {
if (sched_getparam(0, &sched_param) >= 0) {
sched_param.sched_priority = 0;
if (!sched_setscheduler(0, SCHED_RR, &sched_param))
error("sched_setparam failed: %s", strerror(errno));
} else {
error("sched_getparam failed: %s", strerror(errno));
}
}
}
int main(int argc, char *argv[])
{
static const char *const devfiles[] = {
@ -160,6 +182,8 @@ int main(int argc, char *argv[])
int period = 5*60;
int background = 0;
int daemoncmd = 0;
int use_nice = NO_NICE;
int sched_idle = 0;
struct arg *a;
struct option *o;
int i, j, k, res;
@ -251,6 +275,16 @@ int main(int argc, char *argv[])
case 's':
use_syslog = 1;
break;
case 'n':
use_nice = atoi(optarg);
if (use_nice < -20)
use_nice = -20;
else if (use_nice > 19)
use_nice = 19;
break;
case 'c':
sched_idle = 1;
break;
case 'd':
debugflag = 1;
break;
@ -268,6 +302,7 @@ int main(int argc, char *argv[])
}
}
free(short_option);
short_option = NULL;
free(long_option);
long_option = NULL;
if (argc - optind <= 0) {
@ -317,11 +352,14 @@ int main(int argc, char *argv[])
if (removestate)
remove(statefile);
res = load_state(cfgfile, initfile, cardname, init_fallback);
if (!strcmp(cmd, "rdaemon"))
if (!strcmp(cmd, "rdaemon")) {
do_nice(use_nice, sched_idle);
res = state_daemon(cfgfile, cardname, period, pidfile);
}
if (!strcmp(cmd, "nrestore"))
res = state_daemon_kill(pidfile, "rescan");
} else if (!strcmp(cmd, "daemon")) {
do_nice(use_nice, sched_idle);
res = state_daemon(cfgfile, cardname, period, pidfile);
} else if (!strcmp(cmd, "kill")) {
res = state_daemon_kill(pidfile, cardname);