From 79ad4e63f691d1280dde2eb6521a1572c78d03ce Mon Sep 17 00:00:00 2001
From: Lennart Poettering
Date: Wed, 1 Oct 2008 01:14:36 +0200
Subject: [PATCH] Make the shared memory segment size configurable
This is useful only on systems where memory overcommit is not available
or disabled.
---
man/pulse-client.conf.5.xml.in | 9 +++++++++
man/pulse-daemon.conf.5.xml.in | 9 +++++++++
src/daemon/daemon-conf.c | 36 ++++++++++++++++++++----------------
src/daemon/daemon-conf.h | 1 +
src/daemon/daemon.conf.in | 1 +
src/daemon/main.c | 2 +-
src/pulse/client-conf.c | 3 +++
src/pulse/client-conf.h | 1 +
src/pulse/client.conf.in | 1 +
src/pulse/context.c | 4 ++--
src/pulsecore/conf-parser.c | 18 ++++++++++++++++++
src/pulsecore/conf-parser.h | 3 ++-
src/pulsecore/core.c | 8 ++++----
src/pulsecore/core.h | 2 +-
src/pulsecore/memblock.c | 18 ++++++++++++++++--
src/pulsecore/memblock.h | 2 +-
src/tests/envelope-test.c | 2 +-
src/tests/mcalign-test.c | 2 +-
src/tests/memblock-test.c | 6 +++---
src/tests/memblockq-test.c | 2 +-
src/tests/mix-test.c | 2 +-
src/tests/remix-test.c | 2 +-
src/tests/resampler-test.c | 2 +-
23 files changed, 99 insertions(+), 37 deletions(-)
diff --git a/man/pulse-client.conf.5.xml.in b/man/pulse-client.conf.5.xml.in
index ae8de1f..1d6f6fb 100644
--- a/man/pulse-client.conf.5.xml.in
+++ b/man/pulse-client.conf.5.xml.in
@@ -97,6 +97,15 @@ USA.
no.
+
+
diff --git a/man/pulse-daemon.conf.5.xml.in b/man/pulse-daemon.conf.5.xml.in
index ed158df..9d77abf 100644
--- a/man/pulse-daemon.conf.5.xml.in
+++ b/man/pulse-daemon.conf.5.xml.in
@@ -151,6 +151,15 @@ USA.
argument takes precedence.
+
+
diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c
index 77da3f7..939b25d 100644
--- a/src/daemon/daemon-conf.c
+++ b/src/daemon/daemon-conf.c
@@ -84,7 +84,8 @@ static const pa_daemon_conf default_conf = {
.disable_shm = FALSE,
.default_n_fragments = 4,
.default_fragment_size_msec = 25,
- .default_sample_spec = { .format = PA_SAMPLE_S16NE, .rate = 44100, .channels = 2 }
+ .default_sample_spec = { .format = PA_SAMPLE_S16NE, .rate = 44100, .channels = 2 },
+ .shm_size = 0
#ifdef HAVE_SYS_RESOURCE_H
,.rlimit_fsize = { .value = 0, .is_set = FALSE },
.rlimit_data = { .value = 0, .is_set = FALSE },
@@ -429,6 +430,7 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
{ "disable-remixing", pa_config_parse_bool, NULL },
{ "disable-lfe-remixing", pa_config_parse_bool, NULL },
{ "load-default-script-file", pa_config_parse_bool, NULL },
+ { "shm-size-bytes", pa_config_parse_size, NULL },
#ifdef HAVE_SYS_RESOURCE_H
{ "rlimit-fsize", parse_rlimit, NULL },
{ "rlimit-data", parse_rlimit, NULL },
@@ -494,65 +496,66 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
table[26].data = &c->disable_remixing;
table[27].data = &c->disable_lfe_remixing;
table[28].data = &c->load_default_script_file;
+ table[29].data = &c->shm_size;
#ifdef HAVE_SYS_RESOURCE_H
- table[29].data = &c->rlimit_fsize;
- table[30].data = &c->rlimit_data;
- table[31].data = &c->rlimit_stack;
- table[32].data = &c->rlimit_as;
- table[33].data = &c->rlimit_core;
- table[34].data = &c->rlimit_nofile;
- table[35].data = &c->rlimit_as;
+ table[30].data = &c->rlimit_fsize;
+ table[31].data = &c->rlimit_data;
+ table[32].data = &c->rlimit_stack;
+ table[33].data = &c->rlimit_as;
+ table[34].data = &c->rlimit_core;
+ table[35].data = &c->rlimit_nofile;
+ table[36].data = &c->rlimit_as;
#ifdef RLIMIT_NPROC
- table[36].data = &c->rlimit_nproc;
+ table[37].data = &c->rlimit_nproc;
#endif
#ifdef RLIMIT_MEMLOCK
#ifndef RLIMIT_NPROC
#error "Houston, we have a numbering problem!"
#endif
- table[37].data = &c->rlimit_memlock;
+ table[38].data = &c->rlimit_memlock;
#endif
#ifdef RLIMIT_LOCKS
#ifndef RLIMIT_MEMLOCK
#error "Houston, we have a numbering problem!"
#endif
- table[38].data = &c->rlimit_locks;
+ table[39].data = &c->rlimit_locks;
#endif
#ifdef RLIMIT_SIGPENDING
#ifndef RLIMIT_LOCKS
#error "Houston, we have a numbering problem!"
#endif
- table[39].data = &c->rlimit_sigpending;
+ table[40].data = &c->rlimit_sigpending;
#endif
#ifdef RLIMIT_MSGQUEUE
#ifndef RLIMIT_SIGPENDING
#error "Houston, we have a numbering problem!"
#endif
- table[40].data = &c->rlimit_msgqueue;
+ table[41].data = &c->rlimit_msgqueue;
#endif
#ifdef RLIMIT_NICE
#ifndef RLIMIT_MSGQUEUE
#error "Houston, we have a numbering problem!"
#endif
- table[41].data = &c->rlimit_nice;
+ table[42].data = &c->rlimit_nice;
#endif
#ifdef RLIMIT_RTPRIO
#ifndef RLIMIT_NICE
#error "Houston, we have a numbering problem!"
#endif
- table[42].data = &c->rlimit_rtprio;
+ table[43].data = &c->rlimit_rtprio;
#endif
#ifdef RLIMIT_RTTIME
#ifndef RLIMIT_RTTIME
#error "Houston, we have a numbering problem!"
#endif
- table[43].data = &c->rlimit_rttime;
+ table[44].data = &c->rlimit_rttime;
#endif
#endif
@@ -670,6 +673,7 @@ char *pa_daemon_conf_dump(pa_daemon_conf *c) {
pa_strbuf_printf(s, "default-sample-channels = %u\n", c->default_sample_spec.channels);
pa_strbuf_printf(s, "default-fragments = %u\n", c->default_n_fragments);
pa_strbuf_printf(s, "default-fragment-size-msec = %u\n", c->default_fragment_size_msec);
+ pa_strbuf_printf(s, "shm-size-bytes = %lu\n", (unsigned long) c->shm_size);
#ifdef HAVE_SYS_RESOURCE_H
pa_strbuf_printf(s, "rlimit-fsize = %li\n", c->rlimit_fsize.is_set ? (long int) c->rlimit_fsize.value : -1);
pa_strbuf_printf(s, "rlimit-data = %li\n", c->rlimit_data.is_set ? (long int) c->rlimit_data.value : -1);
diff --git a/src/daemon/daemon-conf.h b/src/daemon/daemon-conf.h
index 309a142..9032926 100644
--- a/src/daemon/daemon-conf.h
+++ b/src/daemon/daemon-conf.h
@@ -111,6 +111,7 @@ typedef struct pa_daemon_conf {
unsigned default_n_fragments, default_fragment_size_msec;
pa_sample_spec default_sample_spec;
+ size_t shm_size;
} pa_daemon_conf;
/* Allocate a new structure and fill it with sane defaults */
diff --git a/src/daemon/daemon.conf.in b/src/daemon/daemon.conf.in
index ea09fe0..4362e1c 100644
--- a/src/daemon/daemon.conf.in
+++ b/src/daemon/daemon.conf.in
@@ -26,6 +26,7 @@
; use-pid-file = yes
; system-instance = no
; disable-shm = no
+; shm-size-bytes = 0 # setting this 0 will use the system-default, usually 64 MiB
; high-priority = yes
; nice-level = -11
diff --git a/src/daemon/main.c b/src/daemon/main.c
index a9e8ed4..53f5d19 100644
--- a/src/daemon/main.c
+++ b/src/daemon/main.c
@@ -854,7 +854,7 @@ int main(int argc, char *argv[]) {
pa_assert_se(mainloop = pa_mainloop_new());
- if (!(c = pa_core_new(pa_mainloop_get_api(mainloop), !conf->disable_shm))) {
+ if (!(c = pa_core_new(pa_mainloop_get_api(mainloop), !conf->disable_shm, conf->shm_size))) {
pa_log(_("pa_core_new() failed."));
goto finish;
}
diff --git a/src/pulse/client-conf.c b/src/pulse/client-conf.c
index 739ef16..58d6464 100644
--- a/src/pulse/client-conf.c
+++ b/src/pulse/client-conf.c
@@ -61,6 +61,7 @@ static const pa_client_conf default_conf = {
.disable_shm = FALSE,
.cookie_file = NULL,
.cookie_valid = FALSE,
+ .shm_size = 0
};
pa_client_conf *pa_client_conf_new(void) {
@@ -99,6 +100,7 @@ int pa_client_conf_load(pa_client_conf *c, const char *filename) {
{ "autospawn", pa_config_parse_bool, NULL },
{ "cookie-file", pa_config_parse_string, NULL },
{ "disable-shm", pa_config_parse_bool, NULL },
+ { "shm-size-bytes", pa_config_parse_size, NULL },
{ NULL, NULL, NULL },
};
@@ -110,6 +112,7 @@ int pa_client_conf_load(pa_client_conf *c, const char *filename) {
table[5].data = &c->autospawn;
table[6].data = &c->cookie_file;
table[7].data = &c->disable_shm;
+ table[8].data = &c->shm_size;
if (filename) {
diff --git a/src/pulse/client-conf.h b/src/pulse/client-conf.h
index 699279a..4eac467 100644
--- a/src/pulse/client-conf.h
+++ b/src/pulse/client-conf.h
@@ -31,6 +31,7 @@ typedef struct pa_client_conf {
pa_bool_t autospawn, disable_shm;
uint8_t cookie[PA_NATIVE_COOKIE_LENGTH];
pa_bool_t cookie_valid; /* non-zero, when cookie is valid */
+ size_t shm_size;
} pa_client_conf;
/* Create a new configuration data object and reset it to defaults */
diff --git a/src/pulse/client.conf.in b/src/pulse/client.conf.in
index 8339d65..579bcc2 100644
--- a/src/pulse/client.conf.in
+++ b/src/pulse/client.conf.in
@@ -30,3 +30,4 @@
; cookie-file =
; disable-shm = no
+; shm-size-bytes = 0 # setting this 0 will use the system-default, usually 64 MiB
diff --git a/src/pulse/context.c b/src/pulse/context.c
index 154e5fa..3145d9c 100644
--- a/src/pulse/context.c
+++ b/src/pulse/context.c
@@ -174,10 +174,10 @@ pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *
pa_client_conf_load(c->conf, NULL);
pa_client_conf_env(c->conf);
- if (!(c->mempool = pa_mempool_new(!c->conf->disable_shm))) {
+ if (!(c->mempool = pa_mempool_new(!c->conf->disable_shm, c->conf->shm_size))) {
if (!c->conf->disable_shm)
- c->mempool = pa_mempool_new(FALSE);
+ c->mempool = pa_mempool_new(FALSE, c->conf->shm_size);
if (!c->mempool) {
context_free(c);
diff --git a/src/pulsecore/conf-parser.c b/src/pulsecore/conf-parser.c
index 6b0e1d5..58ceab9 100644
--- a/src/pulsecore/conf-parser.c
+++ b/src/pulsecore/conf-parser.c
@@ -166,6 +166,24 @@ int pa_config_parse_int(const char *filename, unsigned line, const char *lvalue,
return 0;
}
+int pa_config_parse_size(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
+ size_t *i = data;
+ uint32_t k;
+
+ pa_assert(filename);
+ pa_assert(lvalue);
+ pa_assert(rvalue);
+ pa_assert(data);
+
+ if (pa_atou(rvalue, &k) < 0) {
+ pa_log("[%s:%u] Failed to parse numeric value: %s", filename, line, rvalue);
+ return -1;
+ }
+
+ *i = (size_t) k;
+ return 0;
+}
+
int pa_config_parse_bool(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
int k;
pa_bool_t *b = data;
diff --git a/src/pulsecore/conf-parser.h b/src/pulsecore/conf-parser.h
index 7eb1fae..a5174fc 100644
--- a/src/pulsecore/conf-parser.h
+++ b/src/pulsecore/conf-parser.h
@@ -39,8 +39,9 @@ typedef struct pa_config_item {
* NULL */
int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, void *userdata);
-/* Generic parsers for integers, booleans and strings */
+/* Generic parsers for integers, size_t, booleans and strings */
int pa_config_parse_int(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata);
+int pa_config_parse_size(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata);
int pa_config_parse_bool(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata);
int pa_config_parse_string(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata);
diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c
index bd956ae..5761bbc 100644
--- a/src/pulsecore/core.c
+++ b/src/pulsecore/core.c
@@ -66,7 +66,7 @@ static int core_process_msg(pa_msgobject *o, int code, void *userdata, int64_t o
static void core_free(pa_object *o);
-pa_core* pa_core_new(pa_mainloop_api *m, int shared) {
+pa_core* pa_core_new(pa_mainloop_api *m, pa_bool_t shared, size_t shm_size) {
pa_core* c;
pa_mempool *pool;
int j;
@@ -74,14 +74,14 @@ pa_core* pa_core_new(pa_mainloop_api *m, int shared) {
pa_assert(m);
if (shared) {
- if (!(pool = pa_mempool_new(shared))) {
+ if (!(pool = pa_mempool_new(shared, shm_size))) {
pa_log_warn("failed to allocate shared memory pool. Falling back to a normal memory pool.");
- shared = 0;
+ shared = FALSE;
}
}
if (!shared) {
- if (!(pool = pa_mempool_new(shared))) {
+ if (!(pool = pa_mempool_new(shared, shm_size))) {
pa_log("pa_mempool_new() failed.");
return NULL;
}
diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h
index fb4490f..3955908 100644
--- a/src/pulsecore/core.h
+++ b/src/pulsecore/core.h
@@ -141,7 +141,7 @@ enum {
PA_CORE_MESSAGE_MAX
};
-pa_core* pa_core_new(pa_mainloop_api *m, int shared);
+pa_core* pa_core_new(pa_mainloop_api *m, pa_bool_t shared, size_t shm_size);
/* Check whether noone is connected to this core */
void pa_core_check_idle(pa_core *c);
diff --git a/src/pulsecore/memblock.c b/src/pulsecore/memblock.c
index 6d12acd..400a4e1 100644
--- a/src/pulsecore/memblock.c
+++ b/src/pulsecore/memblock.c
@@ -680,8 +680,9 @@ static void memblock_replace_import(pa_memblock *b) {
pa_mutex_unlock(seg->import->mutex);
}
-pa_mempool* pa_mempool_new(pa_bool_t shared) {
+pa_mempool* pa_mempool_new(pa_bool_t shared, size_t size) {
pa_mempool *p;
+ char t1[64], t2[64];
p = pa_xnew(pa_mempool, 1);
@@ -692,13 +693,26 @@ pa_mempool* pa_mempool_new(pa_bool_t shared) {
if (p->block_size < PA_PAGE_SIZE)
p->block_size = PA_PAGE_SIZE;
- p->n_blocks = PA_MEMPOOL_SLOTS_MAX;
+ if (size <= 0)
+ p->n_blocks = PA_MEMPOOL_SLOTS_MAX;
+ else {
+ p->n_blocks = (unsigned) (size / p->block_size);
+
+ if (p->n_blocks < 2)
+ p->n_blocks = 2;
+ }
if (pa_shm_create_rw(&p->memory, p->n_blocks * p->block_size, shared, 0700) < 0) {
pa_xfree(p);
return NULL;
}
+ pa_log_debug("Using %s memory pool with %u slots of size %s each, total size is %s",
+ p->memory.shared ? "shared" : "private",
+ p->n_blocks,
+ pa_bytes_snprint(t1, sizeof(t1), (unsigned) p->block_size),
+ pa_bytes_snprint(t2, sizeof(t2), (unsigned) (p->n_blocks * p->block_size)));
+
memset(&p->stat, 0, sizeof(p->stat));
pa_atomic_store(&p->n_init, 0);
diff --git a/src/pulsecore/memblock.h b/src/pulsecore/memblock.h
index efe55b0..b1eab2a 100644
--- a/src/pulsecore/memblock.h
+++ b/src/pulsecore/memblock.h
@@ -117,7 +117,7 @@ pa_mempool * pa_memblock_get_pool(pa_memblock *b);
pa_memblock *pa_memblock_will_need(pa_memblock *b);
/* The memory block manager */
-pa_mempool* pa_mempool_new(pa_bool_t shared);
+pa_mempool* pa_mempool_new(pa_bool_t shared, size_t size);
void pa_mempool_free(pa_mempool *p);
const pa_mempool_stat* pa_mempool_get_stat(pa_mempool *p);
void pa_mempool_vacuum(pa_mempool *p);
diff --git a/src/tests/envelope-test.c b/src/tests/envelope-test.c
index d71eff1..4a72f5a 100644
--- a/src/tests/envelope-test.c
+++ b/src/tests/envelope-test.c
@@ -205,7 +205,7 @@ int main(int argc, char *argv[]) {
oil_init();
pa_log_set_maximal_level(PA_LOG_DEBUG);
- pa_assert_se(pool = pa_mempool_new(FALSE));
+ pa_assert_se(pool = pa_mempool_new(FALSE, 0));
pa_assert_se(envelope = pa_envelope_new(&ss));
block = generate_block(pool, &ss);
diff --git a/src/tests/mcalign-test.c b/src/tests/mcalign-test.c
index c066582..92e3e14 100644
--- a/src/tests/mcalign-test.c
+++ b/src/tests/mcalign-test.c
@@ -41,7 +41,7 @@ int main(int argc, char *argv[]) {
pa_mcalign *a;
pa_memchunk c;
- p = pa_mempool_new(0);
+ p = pa_mempool_new(FALSE, 0);
a = pa_mcalign_new(11);
diff --git a/src/tests/memblock-test.c b/src/tests/memblock-test.c
index 6da1b1e..37b5b40 100644
--- a/src/tests/memblock-test.c
+++ b/src/tests/memblock-test.c
@@ -78,9 +78,9 @@ int main(int argc, char *argv[]) {
const char txt[] = "This is a test!";
- pool_a = pa_mempool_new(1);
- pool_b = pa_mempool_new(1);
- pool_c = pa_mempool_new(1);
+ pool_a = pa_mempool_new(TRUE, 0);
+ pool_b = pa_mempool_new(TRUE, 0);
+ pool_c = pa_mempool_new(TRUE, 0);
pa_mempool_get_shm_id(pool_a, &id_a);
pa_mempool_get_shm_id(pool_b, &id_b);
diff --git a/src/tests/memblockq-test.c b/src/tests/memblockq-test.c
index 7bf992a..c53945b 100644
--- a/src/tests/memblockq-test.c
+++ b/src/tests/memblockq-test.c
@@ -63,7 +63,7 @@ int main(int argc, char *argv[]) {
pa_log_set_maximal_level(PA_LOG_DEBUG);
- p = pa_mempool_new(0);
+ p = pa_mempool_new(FALSE, 0);
silence.memblock = pa_memblock_new_fixed(p, (char*) "__", 2, 1);
assert(silence.memblock);
diff --git a/src/tests/mix-test.c b/src/tests/mix-test.c
index 544121f..759d769 100644
--- a/src/tests/mix-test.c
+++ b/src/tests/mix-test.c
@@ -201,7 +201,7 @@ int main(int argc, char *argv[]) {
oil_init();
pa_log_set_maximal_level(PA_LOG_DEBUG);
- pa_assert_se(pool = pa_mempool_new(FALSE));
+ pa_assert_se(pool = pa_mempool_new(FALSE, 0));
a.channels = 1;
a.rate = 44100;
diff --git a/src/tests/remix-test.c b/src/tests/remix-test.c
index 4777c15..3538d7d 100644
--- a/src/tests/remix-test.c
+++ b/src/tests/remix-test.c
@@ -58,7 +58,7 @@ int main(int argc, char *argv[]) {
oil_init();
pa_log_set_maximal_level(PA_LOG_DEBUG);
- pa_assert_se(pool = pa_mempool_new(FALSE));
+ pa_assert_se(pool = pa_mempool_new(FALSE, 0));
for (i = 0; maps[i].channels > 0; i++)
for (j = 0; maps[j].channels > 0; j++) {
diff --git a/src/tests/resampler-test.c b/src/tests/resampler-test.c
index 6959127..2d59186 100644
--- a/src/tests/resampler-test.c
+++ b/src/tests/resampler-test.c
@@ -201,7 +201,7 @@ int main(int argc, char *argv[]) {
oil_init();
pa_log_set_maximal_level(PA_LOG_DEBUG);
- pa_assert_se(pool = pa_mempool_new(FALSE));
+ pa_assert_se(pool = pa_mempool_new(FALSE, 0));
a.channels = b.channels = 1;
a.rate = b.rate = 44100;
--
2.7.4