]> code.delx.au - pulseaudio/commitdiff
Make the shared memory segment size configurable
authorLennart Poettering <lennart@poettering.net>
Tue, 30 Sep 2008 23:14:36 +0000 (01:14 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 30 Sep 2008 23:14:36 +0000 (01:14 +0200)
This is useful only on systems where memory overcommit is not available
or disabled.

23 files changed:
man/pulse-client.conf.5.xml.in
man/pulse-daemon.conf.5.xml.in
src/daemon/daemon-conf.c
src/daemon/daemon-conf.h
src/daemon/daemon.conf.in
src/daemon/main.c
src/pulse/client-conf.c
src/pulse/client-conf.h
src/pulse/client.conf.in
src/pulse/context.c
src/pulsecore/conf-parser.c
src/pulsecore/conf-parser.h
src/pulsecore/core.c
src/pulsecore/core.h
src/pulsecore/memblock.c
src/pulsecore/memblock.h
src/tests/envelope-test.c
src/tests/mcalign-test.c
src/tests/memblock-test.c
src/tests/memblockq-test.c
src/tests/mix-test.c
src/tests/remix-test.c
src/tests/resampler-test.c

index ae8de1f80a23026212b09d3348177a95d38f45d4..1d6f6fb41621540f2c9dec555579eab4e1c340c0 100644 (file)
@@ -97,6 +97,15 @@ USA.
       <opt>no</opt>.</p>
     </option>
 
+    <option>
+      <p><opt>shm-size-bytes=</opt> Sets the shared memory segment
+      size for clients, in bytes. If left unspecified or is set to 0
+      it will default to some system-specific default, usually 64
+      MiB. Please note that usually there is no need to change this
+      value, unless you are running an OS kernel that does not do
+      memory overcommit.</p>
+    </option>
+
   </section>
 
   <section name="Authors">
index ed158dfa06ee024e9ae87da83a7b272e0185eab9..9d77abf07f7231399c14cf7bee6907937cbcede0 100644 (file)
@@ -151,6 +151,15 @@ USA.
       argument takes precedence.</p>
     </option>
 
+    <option>
+      <p><opt>shm-size-bytes=</opt> Sets the shared memory segment
+      size for the daemon, in bytes. If left unspecified or is set to 0
+      it will default to some system-specific default, usually 64
+      MiB. Please note that usually there is no need to change this
+      value, unless you are running an OS kernel that does not do
+      memory overcommit.</p>
+    </option>
+
   </section>
 
   <section name="Scheduling">
index 77da3f7ebabea395019eb57403d4d8120bc18255..939b25d776c78a883c206da34ed1e89adf92338e 100644 (file)
@@ -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);
index 309a142850def4ade658ed2e7b67ae585224c29d..90329268e1cc1a1ae8844719a307cf608c6a30c7 100644 (file)
@@ -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 */
index ea09fe09c6fbd7dd1937ece47f4230fa7290a38d..4362e1c162e5fb8c487192c39cfcf4997812744e 100644 (file)
@@ -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
index a9e8ed4626afc94fa85e82c467a1a832106fd6bf..53f5d1938292233f0fe71a154162fd16641f3f78 100644 (file)
@@ -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;
     }
index 739ef1610aae0e8674a02d4092429fb54f070891..58d64642adfb5c3dc6945d4dfbe709b376cfaa13 100644 (file)
@@ -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) {
 
index 699279aaba161a4e6efd62913a1c54571588a905..4eac467ea6518115d5206355612e022dbeb371c4 100644 (file)
@@ -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 */
index 8339d6514aeb294e3992c126150ce5d448485391..579bcc2046fc16665df5130498bb4d43ac1ac4a9 100644 (file)
@@ -30,3 +30,4 @@
 ; cookie-file =
 
 ; disable-shm = no
+; shm-size-bytes = 0 # setting this 0 will use the system-default, usually 64 MiB
index 154e5faf6e4b82297f0d722a9f554260e04e8807..3145d9c80ccdd18ca96c6da6c23faa03b8700bd2 100644 (file)
@@ -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);
index 6b0e1d5670812e010c3eb087ccdedfef30bf1c05..58ceab9171162309dc10810b066253332fb3e353 100644 (file)
@@ -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;
index 7eb1fae2251c89e5389bd3cf35a76e036823606a..a5174fce95e17af3cf533bef6f5c2b0e2562aa45 100644 (file)
@@ -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);
 
index bd956ae0b5b287198a3873e865bca53681b42e73..5761bbc73fb302d8e88d64d54543f5a606a98d69 100644 (file)
@@ -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;
         }
index fb4490f2fc0a5386484ce5e948c770e69add4f80..39559082632cfe30a9cf352e46148f04d7fd068b 100644 (file)
@@ -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);
index 6d12acdca66a98e3e5301633cbd3dd920679cd5e..400a4e1e03a2c4084db32a2ca31068ae9a335ad7 100644 (file)
@@ -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);
 
index efe55b0289fa6d827f448b2fa982cc0198e42c3c..b1eab2a9645edc4383182b4622a701f27badb5a8 100644 (file)
@@ -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);
index d71eff1c1a32031519868bf8e2405f7acd6c9757..4a72f5a3f624a5bbe9d84b3a03848dae2f2364d2 100644 (file)
@@ -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);
index c066582233d62fe9ed39cf6ee3f9f8a46432f1a6..92e3e14e32b86d8bae95b096ecbd97dee44d17cb 100644 (file)
@@ -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);
 
index 6da1b1e9f14dc0a6717312656c270246302412ca..37b5b403a31d458d072c18fc0f6da6de49bafee3 100644 (file)
@@ -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);
index 7bf992a19e18042d3b84858fbe177ccc036864f3..c53945b44c02b1d83b1a287f157db3a1aa6cb29b 100644 (file)
@@ -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);
index 544121fde54cd47107b0ad294cab4064b10797df..759d7690d79149d3455f5406d3f73df6c03250e5 100644 (file)
@@ -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;
index 4777c150958b838e0aacf7e8b724d2d5a9c54945..3538d7d4664297b7d77135ba078bcc349be38270 100644 (file)
@@ -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++) {
index 6959127b5a032b527dd9e55ae496d5bb780c26b9..2d59186760b70c545ac889073362edfd6df41fa1 100644 (file)
@@ -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;