summaryrefslogtreecommitdiff
path: root/alsactl
diff options
context:
space:
mode:
authorJaroslav Kysela <perex@perex.cz>2013-04-10 09:42:40 +0200
committerJaroslav Kysela <perex@perex.cz>2013-04-10 09:42:40 +0200
commit611249ae26f435429dbe1894e210704a723ee277 (patch)
treed7fb8c780a43bf83f8882f680babaefe8bbecf85 /alsactl
parente2eab09c1d7963580d9ff3ec2fbf814a842d2881 (diff)
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>
Diffstat (limited to 'alsactl')
-rw-r--r--alsactl/Makefile.am2
-rw-r--r--alsactl/alsa-state.service.in2
-rw-r--r--alsactl/alsactl.18
-rw-r--r--alsactl/alsactl.c40
4 files changed, 49 insertions, 3 deletions
diff --git a/alsactl/Makefile.am b/alsactl/Makefile.am
index 2a439e9..0659b28 100644
--- a/alsactl/Makefile.am
+++ b/alsactl/Makefile.am
@@ -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 = \
diff --git a/alsactl/alsa-state.service.in b/alsactl/alsa-state.service.in
index 119be1b..fc9914b 100644
--- a/alsactl/alsa-state.service.in
+++ b/alsactl/alsa-state.service.in
@@ -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
diff --git a/alsactl/alsactl.1 b/alsactl/alsactl.1
index 36bd8b5..45ac8a6 100644
--- a/alsactl/alsactl.1
+++ b/alsactl/alsactl.1
@@ -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
diff --git a/alsactl/alsactl.c b/alsactl/alsactl.c
index f00cfff..75baad8 100644
--- a/alsactl/alsactl.c
+++ b/alsactl/alsactl.c
@@ -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);