diff options
36 files changed, 502 insertions, 993 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 0ce805ec..64df8614 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -268,7 +268,8 @@ thread_test_CFLAGS = $(AM_CFLAGS) thread_test_LDADD = $(AM_LDADD) libpulsecore.la thread_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) -flist_test_SOURCES = tests/flist-test.c +flist_test_SOURCES = tests/flist-test.c \ + pulsecore/flist.c pulsecore/flist.h flist_test_CFLAGS = $(AM_CFLAGS) flist_test_LDADD = $(AM_LDADD) libpulsecore.la flist_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) @@ -447,8 +448,6 @@ libpulse_la_SOURCES += \ pulsecore/core-error.c pulsecore/core-error.h \ pulsecore/winsock.h pulsecore/creds.h \ pulsecore/shm.c pulsecore/shm.h \ - pulsecore/flist.c pulsecore/flist.h \ - pulsecore/anotify.c pulsecore/anotify.h \ $(PA_THREAD_OBJS) if OS_IS_WIN32 @@ -629,8 +628,6 @@ libpulsecore_la_SOURCES += \ pulsecore/core-error.c pulsecore/core-error.h \ pulsecore/hook-list.c pulsecore/hook-list.h \ pulsecore/shm.c pulsecore/shm.h \ - pulsecore/flist.c pulsecore/flist.h \ - pulsecore/anotify.c pulsecore/anotify.h \ $(PA_THREAD_OBJS) if OS_IS_WIN32 diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index 7bbd7de2..6ff9a6e4 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -144,7 +144,6 @@ static void do_write(struct userdata *u) { update_usage(u); for (;;) { - void *p; pa_memchunk *memchunk = NULL; snd_pcm_sframes_t frames; @@ -157,15 +156,9 @@ static void do_write(struct userdata *u) { memchunk = &u->memchunk; } - assert(memchunk->memblock); - assert(memchunk->length); - assert((memchunk->length % u->frame_size) == 0); + assert(memchunk->memblock && memchunk->memblock->data && memchunk->length && memchunk->memblock->length && (memchunk->length % u->frame_size) == 0); - p = pa_memblock_acquire(memchunk->memblock); - - if ((frames = snd_pcm_writei(u->pcm_handle, (uint8_t*) p + memchunk->index, memchunk->length / u->frame_size)) < 0) { - pa_memblock_release(memchunk->memblock); - + if ((frames = snd_pcm_writei(u->pcm_handle, (uint8_t*) memchunk->memblock->data + memchunk->index, memchunk->length / u->frame_size)) < 0) { if (frames == -EAGAIN) return; @@ -183,9 +176,6 @@ static void do_write(struct userdata *u) { return; } - pa_memblock_release(memchunk->memblock); - - if (memchunk == &u->memchunk) { size_t l = frames * u->frame_size; memchunk->index += l; diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index 9bde46da..aa0666f1 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -149,7 +149,6 @@ static void do_read(struct userdata *u) { pa_memchunk post_memchunk; snd_pcm_sframes_t frames; size_t l; - void *p; if (!u->memchunk.memblock) { u->memchunk.memblock = pa_memblock_new(u->source->core->mempool, u->memchunk.length = u->fragment_size); @@ -158,13 +157,11 @@ static void do_read(struct userdata *u) { assert(u->memchunk.memblock); assert(u->memchunk.length); + assert(u->memchunk.memblock->data); + assert(u->memchunk.memblock->length); assert(u->memchunk.length % u->frame_size == 0); - p = pa_memblock_acquire(u->memchunk.memblock); - - if ((frames = snd_pcm_readi(u->pcm_handle, (uint8_t*) p + u->memchunk.index, u->memchunk.length / u->frame_size)) < 0) { - pa_memblock_release(u->memchunk.memblock); - + if ((frames = snd_pcm_readi(u->pcm_handle, (uint8_t*) u->memchunk.memblock->data + u->memchunk.index, u->memchunk.length / u->frame_size)) < 0) { if (frames == -EAGAIN) return; @@ -181,7 +178,6 @@ static void do_read(struct userdata *u) { pa_module_unload_request(u->module); return; } - pa_memblock_release(u->memchunk.memblock); l = frames * u->frame_size; diff --git a/src/modules/module-esound-sink.c b/src/modules/module-esound-sink.c index ca1f16ce..6d4a8489 100644 --- a/src/modules/module-esound-sink.c +++ b/src/modules/module-esound-sink.c @@ -142,25 +142,18 @@ static int do_write(struct userdata *u) { u->write_index = u->write_length = 0; } } else if (u->state == STATE_RUNNING) { - void *p; - pa_module_set_used(u->module, pa_sink_used_by(u->sink)); if (!u->memchunk.length) if (pa_sink_render(u->sink, 8192, &u->memchunk) < 0) return 0; - assert(u->memchunk.memblock); - assert(u->memchunk.length); - - p = pa_memblock_acquire(u->memchunk.memblock); + assert(u->memchunk.memblock && u->memchunk.length); - if ((r = pa_iochannel_write(u->io, (uint8_t*) p + u->memchunk.index, u->memchunk.length)) < 0) { - pa_memblock_release(u->memchunk.memblock); + if ((r = pa_iochannel_write(u->io, (uint8_t*) u->memchunk.memblock->data + u->memchunk.index, u->memchunk.length)) < 0) { pa_log("write() failed: %s", pa_cstrerror(errno)); return -1; } - pa_memblock_release(u->memchunk.memblock); u->memchunk.index += r; u->memchunk.length -= r; diff --git a/src/modules/module-jack-sink.c b/src/modules/module-jack-sink.c index 66ded27f..47f77bab 100644 --- a/src/modules/module-jack-sink.c +++ b/src/modules/module-jack-sink.c @@ -135,25 +135,22 @@ static void io_event_cb(pa_mainloop_api *m, pa_io_event *e, int fd, pa_io_event_ unsigned fs; jack_nframes_t frame_idx; pa_memchunk chunk; - void *p; fs = pa_frame_size(&u->sink->sample_spec); pa_sink_render_full(u->sink, u->frames_requested * fs, &chunk); - p = pa_memblock_acquire(chunk.memblock); for (frame_idx = 0; frame_idx < u->frames_requested; frame_idx ++) { unsigned c; for (c = 0; c < u->channels; c++) { - float *s = ((float*) ((uint8_t*) p + chunk.index)) + (frame_idx * u->channels) + c; + float *s = ((float*) ((uint8_t*) chunk.memblock->data + chunk.index)) + (frame_idx * u->channels) + c; float *d = ((float*) u->buffer[c]) + frame_idx; *d = *s; } } - pa_memblock_release(chunk.memblock); pa_memblock_unref(chunk.memblock); u->frames_requested = 0; diff --git a/src/modules/module-jack-source.c b/src/modules/module-jack-source.c index 5270b241..62a99108 100644 --- a/src/modules/module-jack-source.c +++ b/src/modules/module-jack-source.c @@ -134,28 +134,23 @@ static void io_event_cb(pa_mainloop_api *m, pa_io_event *e, int fd, pa_io_event_ unsigned fs; jack_nframes_t frame_idx; pa_memchunk chunk; - void *p; fs = pa_frame_size(&u->source->sample_spec); chunk.memblock = pa_memblock_new(u->core->mempool, chunk.length = u->frames_posted * fs); chunk.index = 0; - - p = pa_memblock_acquire(chunk.memblock); for (frame_idx = 0; frame_idx < u->frames_posted; frame_idx ++) { unsigned c; for (c = 0; c < u->channels; c++) { float *s = ((float*) u->buffer[c]) + frame_idx; - float *d = ((float*) ((uint8_t*) p + chunk.index)) + (frame_idx * u->channels) + c; + float *d = ((float*) ((uint8_t*) chunk.memblock->data + chunk.index)) + (frame_idx * u->channels) + c; *d = *s; } } - pa_memblock_release(chunk.memblock); - pa_source_post(u->source, &chunk); pa_memblock_unref(chunk.memblock); diff --git a/src/modules/module-oss-mmap.c b/src/modules/module-oss-mmap.c index 39a8511f..5ab08287 100644 --- a/src/modules/module-oss-mmap.c +++ b/src/modules/module-oss-mmap.c @@ -170,7 +170,7 @@ static void out_fill_memblocks(struct userdata *u, unsigned n) { u->out_fragment_size, 1); assert(chunk.memblock); - chunk.length = pa_memblock_get_length(chunk.memblock); + chunk.length = chunk.memblock->length; chunk.index = 0; pa_sink_render_into_full(u->sink, &chunk); @@ -214,7 +214,7 @@ static void in_post_memblocks(struct userdata *u, unsigned n) { if (!u->in_memblocks[u->in_current]) { chunk.memblock = u->in_memblocks[u->in_current] = pa_memblock_new_fixed(u->core->mempool, (uint8_t*) u->in_mmap+u->in_fragment_size*u->in_current, u->in_fragment_size, 1); - chunk.length = pa_memblock_get_length(chunk.memblock); + chunk.length = chunk.memblock->length; chunk.index = 0; pa_source_post(u->source, &chunk); diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index 73f0d57e..b71581d9 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -155,7 +155,6 @@ static void do_write(struct userdata *u) { } do { - void *p; memchunk = &u->memchunk; if (!memchunk->length) @@ -163,18 +162,16 @@ static void do_write(struct userdata *u) { memchunk = &u->silence; assert(memchunk->memblock); + assert(memchunk->memblock->data); assert(memchunk->length); - - p = pa_memblock_acquire(memchunk->memblock); - if ((r = pa_iochannel_write(u->io, (uint8_t*) p + memchunk->index, memchunk->length)) < 0) { - pa_memblock_release(memchunk->memblock); + + if ((r = pa_iochannel_write(u->io, (uint8_t*) memchunk->memblock->data + memchunk->index, memchunk->length)) < 0) { pa_log("write() failed: %s", pa_cstrerror(errno)); clear_up(u); pa_module_unload_request(u->module); break; } - pa_memblock_release(memchunk->memblock); if (memchunk == &u->silence) assert(r % u->sample_size == 0); @@ -220,13 +217,9 @@ static void do_read(struct userdata *u) { } do { - void *p; memchunk.memblock = pa_memblock_new(u->core->mempool, l); - - p = pa_memblock_acquire(memchunk.memblock); - - if ((r = pa_iochannel_read(u->io, p, pa_memblock_get_length(memchunk.memblock))) < 0) { - pa_memblock_release(memchunk.memblock); + assert(memchunk.memblock); + if ((r = pa_iochannel_read(u->io, memchunk.memblock->data, memchunk.memblock->length)) < 0) { pa_memblock_unref(memchunk.memblock); if (errno != EAGAIN) { pa_log("read() failed: %s", pa_cstrerror(errno)); @@ -235,10 +228,9 @@ static void do_read(struct userdata *u) { } break; } - pa_memblock_release(memchunk.memblock); - assert(r <= (ssize_t) pa_memblock_get_length(memchunk.memblock)); - memchunk.length = r; + assert(r <= (ssize_t) memchunk.memblock->length); + memchunk.length = memchunk.memblock->length = r; memchunk.index = 0; pa_source_post(u->source, &memchunk); diff --git a/src/modules/module-pipe-sink.c b/src/modules/module-pipe-sink.c index 59d91aa4..4aee849b 100644 --- a/src/modules/module-pipe-sink.c +++ b/src/modules/module-pipe-sink.c @@ -84,8 +84,6 @@ static const char* const valid_modargs[] = { static void do_write(struct userdata *u) { ssize_t r; - void *p; - assert(u); u->core->mainloop->defer_enable(u->defer_event, 0); @@ -99,17 +97,12 @@ static void do_write(struct userdata *u) { if (pa_sink_render(u->sink, PIPE_BUF, &u->memchunk) < 0) return; - assert(u->memchunk.memblock); - assert(u->memchunk.length); - - p = pa_memblock_acquire(u->memchunk.memblock); + assert(u->memchunk.memblock && u->memchunk.length); - if ((r = pa_iochannel_write(u->io, (uint8_t*) p + u->memchunk.index, u->memchunk.length)) < 0) { - pa_memblock_release(u->memchunk.memblock); + if ((r = pa_iochannel_write(u->io, (uint8_t*) u->memchunk.memblock->data + u->memchunk.index, u->memchunk.length)) < 0) { pa_log("write(): %s", pa_cstrerror(errno)); return; } - pa_memblock_release(u->memchunk.memblock); u->memchunk.index += r; u->memchunk.length -= r; diff --git a/src/modules/module-pipe-source.c b/src/modules/module-pipe-source.c index 99f4f3b9..c251f7ac 100644 --- a/src/modules/module-pipe-source.c +++ b/src/modules/module-pipe-source.c @@ -82,9 +82,7 @@ static const char* const valid_modargs[] = { static void do_read(struct userdata *u) { ssize_t r; - void *p; pa_memchunk chunk; - assert(u); if (!pa_iochannel_is_readable(u->io)) @@ -97,22 +95,17 @@ static void do_read(struct userdata *u) { u->chunk.index = chunk.length = 0; } - assert(u->chunk.memblock); - assert(pa_memblock_get_length(u->chunk.memblock) > u->chunk.index); - - p = pa_memblock_acquire(u->chunk.memblock); - if ((r = pa_iochannel_read(u->io, (uint8_t*) p + u->chunk.index, pa_memblock_get_length(u->chunk.memblock) - u->chunk.index)) <= 0) { - pa_memblock_release(u->chunk.memblock); + assert(u->chunk.memblock && u->chunk.memblock->length > u->chunk.index); + if ((r = pa_iochannel_read(u->io, (uint8_t*) u->chunk.memblock->data + u->chunk.index, u->chunk.memblock->length - u->chunk.index)) <= 0) { pa_log("read(): %s", pa_cstrerror(errno)); return; } - pa_memblock_release(u->chunk.memblock); u->chunk.length = r; pa_source_post(u->source, &u->chunk); u->chunk.index += r; - if (u->chunk.index >= pa_memblock_get_length(u->chunk.memblock)) { + if (u->chunk.index >= u->chunk.memblock->length) { u->chunk.index = u->chunk.length = 0; pa_memblock_unref(u->chunk.memblock); u->chunk.memblock = NULL; diff --git a/src/modules/module-sine.c b/src/modules/module-sine.c index f65b1f3a..fa29ba16 100644 --- a/src/modules/module-sine.c +++ b/src/modules/module-sine.c @@ -63,7 +63,7 @@ static int sink_input_peek(pa_sink_input *i, pa_memchunk *chunk) { chunk->memblock = pa_memblock_ref(u->memblock); chunk->index = u->peek_index; - chunk->length = pa_memblock_get_length(u->memblock) - u->peek_index; + chunk->length = u->memblock->length - u->peek_index; return 0; } @@ -72,12 +72,11 @@ static void sink_input_drop(pa_sink_input *i, const pa_memchunk *chunk, size_t l assert(i && chunk && length && i->userdata); u = i->userdata; - assert(chunk->memblock == u->memblock); - assert(length <= pa_memblock_get_length(u->memblock)-u->peek_index); + assert(chunk->memblock == u->memblock && length <= u->memblock->length-u->peek_index); u->peek_index += length; - if (u->peek_index >= pa_memblock_get_length(u->memblock)) + if (u->peek_index >= u->memblock->length) u->peek_index = 0; } @@ -110,7 +109,6 @@ int pa__init(pa_core *c, pa_module*m) { pa_sample_spec ss; uint32_t frequency; char t[256]; - void *p; pa_sink_input_new_data data; if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { @@ -142,10 +140,8 @@ int pa__init(pa_core *c, pa_module*m) { } u->memblock = pa_memblock_new(c->mempool, pa_bytes_per_second(&ss)); - p = pa_memblock_acquire(u->memblock); - calc_sine(p, pa_memblock_get_length(u->memblock), frequency); - pa_memblock_release(u->memblock); - + calc_sine(u->memblock->data, u->memblock->length, frequency); + snprintf(t, sizeof(t), "Sine Generator at %u Hz", frequency); pa_sink_input_new_data_init(&data); diff --git a/src/modules/rtp/rtp.c b/src/modules/rtp/rtp.c index a4362f84..3bb0ea47 100644 --- a/src/modules/rtp/rtp.c +++ b/src/modules/rtp/rtp.c @@ -79,7 +79,7 @@ int pa_rtp_send(pa_rtp_context *c, size_t size, pa_memblockq *q) { size_t k = n + chunk.length > size ? size - n : chunk.length; if (chunk.memblock) { - iov[iov_idx].iov_base = (void*)((uint8_t*) pa_memblock_acquire(chunk.memblock) + chunk.index); + iov[iov_idx].iov_base = (void*)((uint8_t*) chunk.memblock->data + chunk.index); iov[iov_idx].iov_len = k; mb[iov_idx] = chunk.memblock; iov_idx ++; @@ -114,10 +114,8 @@ int pa_rtp_send(pa_rtp_context *c, size_t size, pa_memblockq *q) { k = sendmsg(c->fd, &m, MSG_DONTWAIT); - for (i = 1; i < iov_idx; i++) { - pa_memblock_release(mb[i]); + for (i = 1; i < iov_idx; i++) pa_memblock_unref(mb[i]); - } c->sequence++; } else @@ -174,7 +172,7 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool) { chunk->memblock = pa_memblock_new(pool, size); - iov.iov_base = pa_memblock_acquire(chunk->memblock); + iov.iov_base = chunk->memblock->data; iov.iov_len = size; m.msg_name = NULL; @@ -195,9 +193,9 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool) { goto fail; } - memcpy(&header, iov.iov_base, sizeof(uint32_t)); - memcpy(&c->timestamp, (uint8_t*) iov.iov_base + 4, sizeof(uint32_t)); - memcpy(&c->ssrc, (uint8_t*) iov.iov_base + 8, sizeof(uint32_t)); + memcpy(&header, chunk->memblock->data, sizeof(uint32_t)); + memcpy(&c->timestamp, (uint8_t*) chunk->memblock->data + 4, sizeof(uint32_t)); + memcpy(&c->ssrc, (uint8_t*) chunk->memblock->data + 8, sizeof(uint32_t)); header = ntohl(header); c->timestamp = ntohl(c->timestamp); @@ -238,10 +236,8 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool) { return 0; fail: - if (chunk->memblock) { - pa_memblock_release(chunk->memblock); + if (chunk->memblock) pa_memblock_unref(chunk->memblock); - } return -1; } diff --git a/src/pulse/internal.h b/src/pulse/internal.h index 76d80d83..4eef4b4a 100644 --- a/src/pulse/internal.h +++ b/src/pulse/internal.h @@ -113,7 +113,6 @@ struct pa_stream { uint32_t requested_bytes; pa_memchunk peek_memchunk; - void *peek_data; pa_memblockq *record_memblockq; int corked; diff --git a/src/pulse/stream.c b/src/pulse/stream.c index d31127d8..180cd096 100644 --- a/src/pulse/stream.c +++ b/src/pulse/stream.c @@ -88,7 +88,6 @@ pa_stream *pa_stream_new(pa_context *c, const char *name, const pa_sample_spec * s->peek_memchunk.index = 0; s->peek_memchunk.length = 0; s->peek_memchunk.memblock = NULL; - s->peek_data = NULL; s->record_memblockq = NULL; @@ -123,11 +122,8 @@ static void stream_free(pa_stream *s) { s->mainloop->time_free(s->auto_timing_update_event); } - if (s->peek_memchunk.memblock) { - if (s->peek_data) - pa_memblock_release(s->peek_memchunk.memblock); + if (s->peek_memchunk.memblock) pa_memblock_unref(s->peek_memchunk.memblock); - } if (s->record_memblockq) pa_memblockq_free(s->record_memblockq); @@ -609,11 +605,8 @@ int pa_stream_write( if (free_cb) chunk.memblock = pa_memblock_new_user(s->context->mempool, (void*) data, length, free_cb, 1); else { - void *tdata; chunk.memblock = pa_memblock_new(s->context->mempool, length); - tdata = pa_memblock_acquire(chunk.memblock); - memcpy(tdata, data, length); - pa_memblock_release(chunk.memblock); + memcpy(chunk.memblock->data, data, length); } chunk.index = 0; @@ -679,12 +672,9 @@ int pa_stream_peek(pa_stream *s, const void **data, size_t *length) { *length = 0; return 0; } - - s->peek_data = pa_memblock_acquire(s->peek_memchunk.memblock); } - assert(s->peek_data); - *data = (uint8_t*) s->peek_data + s->peek_memchunk.index; + *data = (const char*) s->peek_memchunk.memblock->data + s->peek_memchunk.index; *length = s->peek_memchunk.length; return 0; } @@ -702,9 +692,7 @@ int pa_stream_drop(pa_stream *s) { /* Fix the simulated local read index */ if (s->timing_info_valid && !s->timing_info.read_index_corrupt) s->timing_info.read_index += s->peek_memchunk.length; - - assert(s->peek_data); - pa_memblock_release(s->peek_memchunk.memblock); + pa_memblock_unref(s->peek_memchunk.memblock); s->peek_memchunk.length = 0; s->peek_memchunk.index = 0; diff --git a/src/pulsecore/cli-command.c b/src/pulsecore/cli-command.c index d7e4a75c..ae475c3a 100644 --- a/src/pulsecore/cli-command.c +++ b/src/pulsecore/cli-command.c @@ -259,20 +259,20 @@ static int pa_cli_command_stat(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_G stat = pa_mempool_get_stat(c->mempool); pa_strbuf_printf(buf, "Memory blocks currently allocated: %u, size: %s.\n", - (unsigned) pa_atomic_load(&stat->n_allocated), - pa_bytes_snprint(s, sizeof(s), (size_t) pa_atomic_load(&stat->allocated_size))); + (unsigned) AO_load_acquire_read((AO_t*) &stat->n_allocated), + pa_bytes_snprint(s, sizeof(s), (size_t) AO_load_acquire_read((AO_t*) &stat->allocated_size))); pa_strbuf_printf(buf, "Memory blocks allocated during the whole lifetime: %u, size: %s.\n", - (unsigned) pa_atomic_load(&stat->n_accumulated), - pa_bytes_snprint(s, sizeof(s), (size_t) pa_atomic_load(&stat->accumulated_size))); + (unsigned) AO_load_acquire_read((AO_t*) &stat->n_accumulated), + pa_bytes_snprint(s, sizeof(s), (size_t) AO_load_acquire_read((AO_t*) &stat->accumulated_size))); pa_strbuf_printf(buf, "Memory blocks imported from other processes: %u, size: %s.\n", - (unsigned) pa_atomic_load(&stat->n_imported), - pa_bytes_snprint(s, sizeof(s), (size_t) pa_atomic_load(&stat->imported_size))); + (unsigned) AO_load_acquire_read((AO_t*) &stat->n_imported), + pa_bytes_snprint(s, sizeof(s), (size_t) AO_load_acquire_read((AO_t*) &stat->imported_size))); pa_strbuf_printf(buf, "Memory blocks exported to other processes: %u, size: %s.\n", - (unsigned) pa_atomic_load(&stat->n_exported), - pa_bytes_snprint(s, sizeof(s), (size_t) pa_atomic_load(&stat->exported_size))); + (unsigned) AO_load_acquire_read((AO_t*) &stat->n_exported), + pa_bytes_snprint(s, sizeof(s), (size_t) AO_load_acquire_read((AO_t*) &stat->exported_size))); pa_strbuf_printf(buf, "Total sample cache size: %s.\n", pa_bytes_snprint(s, sizeof(s), pa_scache_total_size(c))); @@ -289,8 +289,8 @@ static int pa_cli_command_stat(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_G pa_strbuf_printf(buf, "Memory blocks of type %s: %u allocated/%u accumulated.\n", type_table[k], - (unsigned) pa_atomic_load(&stat->n_allocated_by_type[k]), - (unsigned) pa_atomic_load(&stat->n_accumulated_by_type[k])); + (unsigned) AO_load_acquire_read(&stat->n_allocated_by_type[k]), + (unsigned) AO_load_acquire_read(&stat->n_accumulated_by_type[k])); return 0; } diff --git a/src/pulsecore/mcalign.c b/src/pulsecore/mcalign.c index aa2eae46..9ede610d 100644 --- a/src/pulsecore/mcalign.c +++ b/src/pulsecore/mcalign.c @@ -89,7 +89,6 @@ void pa_mcalign_push(pa_mcalign *m, const pa_memchunk *c) { } else { size_t l; - void *lo_data, *m_data; /* We have to copy */ assert(m->leftover.length < m->base); @@ -101,15 +100,10 @@ void pa_mcalign_push(pa_mcalign *m, const pa_memchunk *c) { /* Can we use the current block? */ pa_memchunk_make_writable(&m->leftover, m->base); - lo_data = pa_memblock_acquire(m->leftover.memblock); - m_data = pa_memblock_acquire(c->memblock); - memcpy((uint8_t*) lo_data + m->leftover.index + m->leftover.length, (uint8_t*) m_data + c->index, l); - pa_memblock_release(m->leftover.memblock); - pa_memblock_release(c->memblock); + memcpy((uint8_t*) m->leftover.memblock->data + m->leftover.index + m->leftover.length, (uint8_t*) c->memblock->data + c->index, l); m->leftover.length += l; - assert(m->leftover.length <= m->base); - assert(m->leftover.length <= pa_memblock_get_length(m->leftover.memblock)); + assert(m->leftover.length <= m->base && m->leftover.length <= m->leftover.memblock->length); if (c->length > l) { /* Save the remainder of the memory block */ diff --git a/src/pulsecore/memblock.c b/src/pulsecore/memblock.c index f11a7174..9cfd79b5 100644 --- a/src/pulsecore/memblock.c +++ b/src/pulsecore/memblock.c @@ -30,13 +30,10 @@ #include <unistd.h> #include <pulse/xmalloc.h> -#include <pulse/def.h> #include <pulsecore/shm.h> #include <pulsecore/log.h> #include <pulsecore/hashmap.h> -#include <pulsecore/mutex.h> -#include <pulsecore/flist.h> #include "memblock.h" @@ -48,32 +45,6 @@ #define PA_MEMIMPORT_SLOTS_MAX 128 #define PA_MEMIMPORT_SEGMENTS_MAX 16 -struct pa_memblock { - PA_REFCNT_DECLARE; /* the reference counter */ - pa_mempool *pool; - - pa_memblock_type_t type; - int read_only; /* boolean */ - - pa_atomic_ptr_t data; - size_t length; - - pa_atomic_int_t n_acquired; - pa_atomic_int_t please_signal; - - union { - struct { - /* If type == PA_MEMBLOCK_USER this points to a function for freeing this memory block */ - pa_free_cb_t free_cb; - } user; - - struct { - uint32_t id; - pa_memimport_segment *segment; - } imported; - } per_type; -}; - struct pa_memimport_segment { pa_memimport *import; pa_shm memory; @@ -81,8 +52,6 @@ struct pa_memimport_segment { }; struct pa_memimport { - pa_mutex *mutex; - pa_mempool *pool; pa_hashmap *segments; pa_hashmap *blocks; @@ -101,11 +70,9 @@ struct memexport_slot { }; struct pa_memexport { - pa_mutex *mutex; pa_mempool *pool; struct memexport_slot slots[PA_MEMEXPORT_SLOTS_MAX]; - PA_LLIST_HEAD(struct memexport_slot, free_slots); PA_LLIST_HEAD(struct memexport_slot, used_slots); unsigned n_init; @@ -125,71 +92,63 @@ struct mempool_slot { }; struct pa_mempool { - pa_mutex *mutex; - pa_cond *cond; - pa_shm memory; size_t block_size; - unsigned n_blocks; - - pa_atomic_int_t n_init; + unsigned n_blocks, n_init; PA_LLIST_HEAD(pa_memimport, imports); PA_LLIST_HEAD(pa_memexport, exports); /* A list of free slots that may be reused */ - pa_flist *free_slots; + PA_LLIST_HEAD(struct mempool_slot, free_slots); pa_mempool_stat stat; }; static void segment_detach(pa_memimport_segment *seg); -/* No lock necessary */ static void stat_add(pa_memblock*b) { assert(b); assert(b->pool); - pa_atomic_inc(&b->pool->stat.n_allocated); - pa_atomic_add(&b->pool->stat.allocated_size, (int) b->length); + AO_fetch_and_add1_release_write(&b->pool->stat.n_allocated); + AO_fetch_and_add_release_write(&b->pool->stat.allocated_size, (AO_t) b->length); - pa_atomic_inc(&b->pool->stat.n_accumulated); - pa_atomic_add(&b->pool->stat.accumulated_size, (int) b->length); + AO_fetch_and_add1_release_write(&b->pool->stat.n_accumulated); + AO_fetch_and_add_release_write(&b->pool->stat.accumulated_size, (AO_t) b->length); if (b->type == PA_MEMBLOCK_IMPORTED) { - pa_atomic_inc(&b->pool->stat.n_imported); - pa_atomic_add(&b->pool->stat.imported_size, (int) b->length); + AO_fetch_and_add1_release_write(&b->pool->stat.n_imported); + AO_fetch_and_add_release_write(&b->pool->stat.imported_size, (AO_t) b->length); } - pa_atomic_inc(&b->pool->stat.n_allocated_by_type[b->type]); - pa_atomic_inc(&b->pool->stat.n_accumulated_by_type[b->type]); + AO_fetch_and_add1_release_write(&b->pool->stat.n_allocated_by_type[b->type]); + AO_fetch_and_add1_release_write(&b->pool->stat.n_accumulated_by_type[b->type]); } -/* No lock necessary */ static void stat_remove(pa_memblock *b) { assert(b); assert(b->pool); - assert(pa_atomic_load(&b->pool->stat.n_allocated) > 0); - assert(pa_atomic_load(&b->pool->stat.allocated_size) >= (int) b->length); + assert(AO_load_acquire_read(&b->pool->stat.n_allocated) > 0); + assert(AO_load_acquire_read(&b->pool->stat.allocated_size) >= (AO_t) b->length); - pa_atomic_dec(&b->pool->stat.n_allocated); - pa_atomic_add(&b->pool->stat.allocated_size, - (int) b->length); + AO_fetch_and_sub1_release_write(&b->pool->stat.n_allocated); + AO_fetch_and_add_release_write(&b->pool->stat.allocated_size, (AO_t) (-b->length)); if (b->type == PA_MEMBLOCK_IMPORTED) { - assert(pa_atomic_load(&b->pool->stat.n_imported) > 0); - assert(pa_atomic_load(&b->pool->stat.imported_size) >= (int) b->length); + assert(AO_load_acquire_read(&b->pool->stat.n_imported) > 0); + assert(AO_load_acquire_read(&b->pool->stat.imported_size) >= (AO_t) b->length); - pa_atomic_dec(&b->pool->stat.n_imported); - pa_atomic_add(&b->pool->stat.imported_size, - (int) b->length); + AO_fetch_and_sub1_release_write(&b->pool->stat.n_imported); + AO_fetch_and_add_release_write(&b->pool->stat.imported_size, (AO_t) (-b->length)); } - pa_atomic_dec(&b->pool->stat.n_allocated_by_type[b->type]); + AO_fetch_and_sub1_release_write(&b->pool->stat.n_allocated_by_type[b->type]); } static pa_memblock *memblock_new_appended(pa_mempool *p, size_t length); -/* No lock necessary */ pa_memblock *pa_memblock_new(pa_mempool *p, size_t length) { pa_memblock *b; @@ -202,7 +161,6 @@ pa_memblock *pa_memblock_new(pa_mempool *p, size_t length) { return b; } -/* No lock necessary */ static pa_memblock *memblock_new_appended(pa_mempool *p, size_t length) { pa_memblock *b; @@ -210,61 +168,49 @@ static pa_memblock *memblock_new_appended(pa_mempool *p, size_t length) { assert(length > 0); b = pa_xmalloc(sizeof(pa_memblock) + length); - PA_REFCNT_INIT(b); - b->pool = p; b->type = PA_MEMBLOCK_APPENDED; b->read_only = 0; - pa_atomic_ptr_store(&b->data, (uint8_t*)b + sizeof(pa_memblock)); + PA_REFCNT_INIT(b); b->length = length; - pa_atomic_store(&b->n_acquired, 0); - pa_atomic_store(&b->please_signal, 0); - + b->data = (uint8_t*) b + sizeof(pa_memblock); + b->pool = p; + stat_add(b); return b; } -/* No lock necessary */ static struct mempool_slot* mempool_allocate_slot(pa_mempool *p) { struct mempool_slot *slot; assert(p); - if (!(slot = pa_flist_pop(p->free_slots))) { - int idx; - - /* The free list was empty, we have to allocate a new entry */ - - if ((unsigned) (idx = pa_atomic_inc(&p->n_init)) >= p->n_blocks) - pa_atomic_dec(&p->n_init); - else - slot = (struct mempool_slot*) ((uint8_t*) p->memory.ptr + (p->block_size * idx)); - - if (!slot) { - pa_log_debug("Pool full"); - pa_atomic_inc(&p->stat.n_pool_full); - } + if (p->free_slots) { + slot = p->free_slots; + PA_LLIST_REMOVE(struct mempool_slot, p->free_slots, slot); + } else if (p->n_init < p->n_blocks) + slot = (struct mempool_slot*) ((uint8_t*) p->memory.ptr + (p->block_size * p->n_init++)); + else { + pa_log_debug("Pool full"); + AO_fetch_and_add1_release_write(&p->stat.n_pool_full); + return NULL; } return slot; } -/* No lock necessary */ static void* mempool_slot_data(struct mempool_slot *slot) { assert(slot); return (uint8_t*) slot + sizeof(struct mempool_slot); } -/* No lock necessary */ static unsigned mempool_slot_idx(pa_mempool *p, void *ptr) { assert(p); - assert((uint8_t*) ptr >= (uint8_t*) p->memory.ptr); assert((uint8_t*) ptr < (uint8_t*) p->memory.ptr + p->memory.size); return ((uint8_t*) ptr - (uint8_t*) p->memory.ptr) / p->block_size; } -/* No lock necessary */ static struct mempool_slot* mempool_slot_by_ptr(pa_mempool *p, void *ptr) { unsigned idx; @@ -274,7 +220,6 @@ static struct mempool_slot* mempool_slot_by_ptr(pa_mempool *p, void *ptr) { return (struct mempool_slot*) ((uint8_t*) p->memory.ptr + (idx * p->block_size)); } -/* No lock necessary */ pa_memblock *pa_memblock_new_pool(pa_mempool *p, size_t length) { pa_memblock *b = NULL; struct mempool_slot *slot; @@ -289,7 +234,7 @@ pa_memblock *pa_memblock_new_pool(pa_mempool *p, size_t length) { b = mempool_slot_data(slot); b->type = PA_MEMBLOCK_POOL; - pa_atomic_ptr_store(&b->data, (uint8_t*) b + sizeof(pa_memblock)); + b->data = (uint8_t*) b + sizeof(pa_memblock); } else if (p->block_size - sizeof(struct mempool_slot) >= length) { @@ -298,26 +243,22 @@ pa_memblock *pa_memblock_new_pool(pa_mempool *p, size_t length) { b = pa_xnew(pa_memblock, 1); b->type = PA_MEMBLOCK_POOL_EXTERNAL; - pa_atomic_ptr_store(&b->data, mempool_slot_data(slot)); - + b->data = mempool_slot_data(slot); } else { pa_log_debug("Memory block too large for pool: %u > %u", length, p->block_size - sizeof(struct mempool_slot)); - pa_atomic_inc(&p->stat.n_too_large_for_pool); + AO_fetch_and_add1_release_write(&p->stat.n_too_large_for_pool); return NULL; } + b->length = length; + b->read_only = 0; PA_REFCNT_INIT(b); b->pool = p; - b->read_only = 0; - b->length = length; - pa_atomic_store(&b->n_acquired, 0); - pa_atomic_store(&b->please_signal, 0); stat_add(b); return b; } -/* No lock necessary */ pa_memblock *pa_memblock_new_fixed(pa_mempool *p, void *d, size_t length, int read_only) { pa_memblock *b; @@ -326,20 +267,17 @@ pa_memblock *pa_memblock_new_fixed(pa_mempool *p, void *d, size_t length, int re assert(length > 0); b = pa_xnew(pa_memblock, 1); - PA_REFCNT_INIT(b); - b->pool = p; b->type = PA_MEMBLOCK_FIXED; b->read_only = read_only; - pa_atomic_ptr_store(&b->data, d); + PA_REFCNT_INIT(b); b->length = length; - pa_atomic_store(&b->n_acquired, 0); - pa_atomic_store(&b->please_signal, 0); + b->data = d; + b->pool = p; stat_add(b); return b; } -/* No lock necessary */ pa_memblock *pa_memblock_new_user(pa_mempool *p, void *d, size_t length, void (*free_cb)(void *p), int read_only) { pa_memblock *b; @@ -349,72 +287,18 @@ pa_memblock *pa_memblock_new_user(pa_mempool *p, void *d, size_t length, void (* assert(free_cb); b = pa_xnew(pa_memblock, 1); - PA_REFCNT_INIT(b); - b->pool = p; b->type = PA_MEMBLOCK_USER; b->read_only = read_only; - pa_atomic_ptr_store(&b->data, d); + PA_REFCNT_INIT(b); b->length = length; - pa_atomic_store(&b->n_acquired, 0); - pa_atomic_store(&b->please_signal, 0); - + b->data = d; b->per_type.user.free_cb = free_cb; + b->pool = p; stat_add(b); return b; } -/* No lock necessary */ -int pa_memblock_is_read_only(pa_memblock *b) { - assert(b); - assert(PA_REFCNT_VALUE(b) > 0); - - return b->read_only && PA_REFCNT_VALUE(b) == 1; -} - -/* No lock necessary */ -void* pa_memblock_acquire(pa_memblock *b) { - assert(b); - assert(PA_REFCNT_VALUE(b) > 0); - - pa_atomic_inc(&b->n_acquired); - - return pa_atomic_ptr_load(&b->data); -} - -/* No lock necessary, in corner cases locks by its own */ -void pa_memblock_release(pa_memblock *b) { - int r; - assert(b); - assert(PA_REFCNT_VALUE(b) > 0); - - r = pa_atomic_dec(&b->n_acquired); - assert(r >= 1); - - if (r == 1 && pa_atomic_load(&b->please_signal)) { - pa_mempool *p = b->pool; - /* Signal a waiting thread that this memblock is no longer used */ - pa_mutex_lock(p->mutex); - pa_cond_signal(p->cond, 1); - pa_mutex_unlock(p->mutex); - } -} - -size_t pa_memblock_get_length(pa_memblock *b) { - assert(b); - assert(PA_REFCNT_VALUE(b) > 0); - - return b->length; -} - -pa_mempool* pa_memblock_get_pool(pa_memblock *b) { - assert(b); - assert(PA_REFCNT_VALUE(b) > 0); - - return b->pool; -} - -/* No lock necessary */ pa_memblock* pa_memblock_ref(pa_memblock*b) { assert(b); assert(PA_REFCNT_VALUE(b) > 0); @@ -423,17 +307,19 @@ pa_memblock* pa_memblock_ref(pa_memblock*b) { return b; } -static void memblock_free(pa_memblock *b) { +void pa_memblock_unref(pa_memblock*b) { assert(b); - - assert(pa_atomic_load(&b->n_acquired) == 0); + assert(PA_REFCNT_VALUE(b) > 0); + if (PA_REFCNT_DEC(b) > 0) + return; + stat_remove(b); switch (b->type) { case PA_MEMBLOCK_USER : assert(b->per_type.user.free_cb); - b->per_type.user.free_cb(pa_atomic_ptr_load(&b->data)); + b->per_type.user.free_cb(b->data); /* Fall through */ @@ -444,23 +330,17 @@ static void memblock_free(pa_memblock *b) { case PA_MEMBLOCK_IMPORTED : { pa_memimport_segment *segment; - pa_memimport *import; - - /* FIXME! This should be implemented lock-free */ - + segment = b->per_type.imported.segment; assert(segment); - import = segment->import; - assert(import); + assert(segment->import); - pa_mutex_lock(import->mutex); - pa_hashmap_remove(import->blocks, PA_UINT32_TO_PTR(b->per_type.imported.id)); + pa_hashmap_remove(segment->import->blocks, PA_UINT32_TO_PTR(b->per_type.imported.id)); + segment->import->release_cb(segment->import, b->per_type.imported.id, segment->import->userdata); + if (-- segment->n_blocks <= 0) segment_detach(segment); - pa_mutex_unlock(import->mutex); - - import->release_cb(import, b->per_type.imported.id, import->userdata); - + pa_xfree(b); break; } @@ -468,20 +348,13 @@ static void memblock_free(pa_memblock *b) { case PA_MEMBLOCK_POOL_EXTERNAL: case PA_MEMBLOCK_POOL: { struct mempool_slot *slot; - int call_free; - slot = mempool_slot_by_ptr(b->pool, pa_atomic_ptr_load(&b->data)); + slot = mempool_slot_by_ptr(b->pool, b->data); assert(slot); - - call_free = b->type == PA_MEMBLOCK_POOL_EXTERNAL; - - /* The free list dimensions should easily allow all slots - * to fit in, hence try harder if pushing this slot into - * the free list fails */ - while (pa_flist_push(b->pool->free_slots, slot) < 0) - ; - if (call_free) + PA_LLIST_PREPEND(struct mempool_slot, b->pool->free_slots, slot); + + if (b->type == PA_MEMBLOCK_POOL_EXTERNAL) pa_xfree(b); break; @@ -493,42 +366,10 @@ static void memblock_free(pa_memblock *b) { } } -/* No lock necessary */ -void pa_memblock_unref(pa_memblock*b) { - assert(b); - assert(PA_REFCNT_VALUE(b) > 0); - - if (PA_REFCNT_DEC(b) > 0) - return; - - memblock_free(b); -} - -/* Self locked */ -static void memblock_wait(pa_memblock *b) { - assert(b); - - if (pa_atomic_load(&b->n_acquired) > 0) { - /* We need to wait until all threads gave up access to the - * memory block before we can go on. Unfortunately this means - * that we have to lock and wait here. Sniff! */ - - pa_atomic_inc(&b->please_signal); - - pa_mutex_lock(b->pool->mutex); - while (pa_atomic_load(&b->n_acquired) > 0) - pa_cond_wait(b->pool->cond, b->pool->mutex); - pa_mutex_unlock(b->pool->mutex); - - pa_atomic_dec(&b->please_signal); - } -} - -/* No lock necessary. This function is not multiple caller safe! */ static void memblock_make_local(pa_memblock *b) { assert(b); - pa_atomic_dec(&b->pool->stat.n_allocated_by_type[b->type]); + AO_fetch_and_sub1_release_write(&b->pool->stat.n_allocated_by_type[b->type]); if (b->length <= b->pool->block_size - sizeof(struct mempool_slot)) { struct mempool_slot *slot; @@ -537,61 +378,53 @@ static void memblock_make_local(pa_memblock *b) { void *new_data; /* We can move it into a local pool, perfect! */ - new_data = mempool_slot_data(slot); - memcpy(new_data, pa_atomic_ptr_load(&b->data), b->length); - pa_atomic_ptr_store(&b->data, new_data); - b->type = PA_MEMBLOCK_POOL_EXTERNAL; b->read_only = 0; + new_data = mempool_slot_data(slot); + memcpy(new_data, b->data, b->length); + b->data = new_data; goto finish; } } /* Humm, not enough space in the pool, so lets allocate the memory with malloc() */ - b->per_type.user.free_cb = pa_xfree; - pa_atomic_ptr_store(&b->data, pa_xmemdup(pa_atomic_ptr_load(&b->data), b->length)); - b->type = PA_MEMBLOCK_USER; + b->per_type.user.free_cb = pa_xfree; b->read_only = 0; + b->data = pa_xmemdup(b->data, b->length); finish: - pa_atomic_inc(&b->pool->stat.n_allocated_by_type[b->type]); - pa_atomic_inc(&b->pool->stat.n_accumulated_by_type[b->type]); - - memblock_wait(b); + AO_fetch_and_add1_release_write(&b->pool->stat.n_allocated_by_type[b->type]); + AO_fetch_and_add1_release_write(&b->pool->stat.n_accumulated_by_type[b->type]); } -/* No lock necessary. This function is not multiple caller safe*/ void pa_memblock_unref_fixed(pa_memblock *b) { assert(b); assert(PA_REFCNT_VALUE(b) > 0); assert(b->type == PA_MEMBLOCK_FIXED); - if (PA_REFCNT_DEC(b) > 0) + if (PA_REFCNT_VALUE(b) > 1) memblock_make_local(b); - else - memblock_free(b); + + pa_memblock_unref(b); } -/* Self-locked. This function is not multiple-caller safe */ static void memblock_replace_import(pa_memblock *b) { pa_memimport_segment *seg; assert(b); assert(b->type == PA_MEMBLOCK_IMPORTED); - assert(pa_atomic_load(&b->pool->stat.n_imported) > 0); - assert(pa_atomic_load(&b->pool->stat.imported_size) >= (int) b->length); - pa_atomic_dec(&b->pool->stat.n_imported); - pa_atomic_add(&b->pool->stat.imported_size, (int) - b->length); + assert(AO_load_acquire_read(&b->pool->stat.n_imported) > 0); + assert(AO_load_acquire_read(&b->pool->stat.imported_size) >= (AO_t) b->length); + AO_fetch_and_sub1_release_write(&b->pool->stat.n_imported); + AO_fetch_and_add_release_write(&b->pool->stat.imported_size, (AO_t) - b->length); seg = b->per_type.imported.segment; assert(seg); assert(seg->import); - pa_mutex_lock(seg->import->mutex); - pa_hashmap_remove( seg->import->blocks, PA_UINT32_TO_PTR(b->per_type.imported.id)); @@ -600,8 +433,6 @@ static void memblock_replace_import(pa_memblock *b) { if (-- seg->n_blocks <= 0) segment_detach(seg); - - pa_mutex_unlock(seg->import->mutex); } pa_mempool* pa_mempool_new(int shared) { @@ -610,15 +441,12 @@ pa_mempool* pa_mempool_new(int shared) { p = pa_xnew(pa_mempool, 1); - p->mutex = pa_mutex_new(1); - p->cond = pa_cond_new(); - #ifdef HAVE_SYSCONF ps = (size_t) sysconf(_SC_PAGESIZE); #elif defined(PAGE_SIZE) - ps = (size_t) PAGE_SIZE; + ps = (size_t) PAGE_SIZE; #else - ps = 4096; /* Let's hope it's like x86. */ + ps = 4096; /* Let's hope it's like x86. */ #endif p->block_size = (PA_MEMPOOL_SLOT_SIZE/ps)*ps; @@ -635,13 +463,13 @@ pa_mempool* pa_mempool_new(int shared) { return NULL; } - memset(&p->stat, 0, sizeof(p->stat)); - pa_atomic_store(&p->n_init, 0); + p->n_init = 0; PA_LLIST_HEAD_INIT(pa_memimport, p->imports); PA_LLIST_HEAD_INIT(pa_memexport, p->exports); + PA_LLIST_HEAD_INIT(struct mempool_slot, p->free_slots); - p->free_slots = pa_flist_new(p->n_blocks*2); + memset(&p->stat, 0, sizeof(p->stat)); return p; } @@ -649,62 +477,34 @@ pa_mempool* pa_mempool_new(int shared) { void pa_mempool_free(pa_mempool *p) { assert(p); - pa_mutex_lock(p->mutex); - while (p->imports) pa_memimport_free(p->imports); while (p->exports) pa_memexport_free(p->exports); - pa_mutex_unlock(p->mutex); - - if (pa_atomic_load(&p->stat.n_allocated) > 0) + if (AO_load_acquire_read(&p->stat.n_allocated) > 0) pa_log_warn("WARNING! Memory pool destroyed but not all memory blocks freed!"); - - pa_flist_free(p->free_slots, NULL); pa_shm_free(&p->memory); - - pa_mutex_free(p->mutex); - pa_cond_free(p->cond); - pa_xfree(p); } -/* No lock necessary */ const pa_mempool_stat* pa_mempool_get_stat(pa_mempool *p) { assert(p); return &p->stat; } -/* No lock necessary */ void pa_mempool_vacuum(pa_mempool *p) { struct mempool_slot *slot; - pa_flist *list; assert(p); - list = pa_flist_new(p->n_blocks*2); - - while ((slot = pa_flist_pop(p->free_slots))) - while (pa_flist_push(list, slot) < 0) - ; - - while ((slot = pa_flist_pop(list))) { - pa_shm_punch(&p->memory, - (uint8_t*) slot - (uint8_t*) p->memory.ptr + sizeof(struct mempool_slot), - p->block_size - sizeof(struct mempool_slot)); - - while (pa_flist_push(p->free_slots, slot)) - ; - } - - pa_flist_free(list, NULL); + for (slot = p->free_slots; slot; slot = slot->next) + pa_shm_punch(&p->memory, (uint8_t*) slot + sizeof(struct mempool_slot) - (uint8_t*) p->memory.ptr, p->block_size - sizeof(struct mempool_slot)); } -/* No lock necessary */ int pa_mempool_get_shm_id(pa_mempool *p, uint32_t *id) { assert(p); @@ -716,7 +516,6 @@ int pa_mempool_get_shm_id(pa_mempool *p, uint32_t *id) { return 0; } -/* No lock necessary */ int pa_mempool_is_shared(pa_mempool *p) { assert(p); @@ -731,23 +530,18 @@ pa_memimport* pa_memimport_new(pa_mempool *p, pa_memimport_release_cb_t cb, void assert(cb); i = pa_xnew(pa_memimport, 1); - i->mutex = pa_mutex_new(0); i->pool = p; i->segments = pa_hashmap_new(NULL, NULL); i->blocks = pa_hashmap_new(NULL, NULL); i->release_cb = cb; i->userdata = userdata; - - pa_mutex_lock(p->mutex); + PA_LLIST_PREPEND(pa_memimport, p->imports, i); - pa_mutex_unlock(p->mutex); - return i; } static void memexport_revoke_blocks(pa_memexport *e, pa_memimport *i); -/* Should be called locked */ static pa_memimport_segment* segment_attach(pa_memimport *i, uint32_t shm_id) { pa_memimport_segment* seg; @@ -768,7 +562,6 @@ static pa_memimport_segment* segment_attach(pa_memimport *i, uint32_t shm_id) { return seg; } -/* Should be called locked */ static void segment_detach(pa_memimport_segment *seg) { assert(seg); @@ -777,68 +570,51 @@ static void segment_detach(pa_memimport_segment *seg) { pa_xfree(seg); } -/* Self-locked. Not multiple-caller safe */ void pa_memimport_free(pa_memimport *i) { pa_memexport *e; pa_memblock *b; assert(i); - pa_mutex_lock(i->mutex); + /* If we've exported this block further we need to revoke that export */ + for (e = i->pool->exports; e; e = e->next) + memexport_revoke_blocks(e, i); while ((b = pa_hashmap_get_first(i->blocks))) memblock_replace_import(b); assert(pa_hashmap_size(i->segments) == 0); - - pa_mutex_unlock(i->mutex); - - pa_mutex_lock(i->pool->mutex); - - /* If we've exported this block further we need to revoke that export */ - for (e = i->pool->exports; e; e = e->next) - memexport_revoke_blocks(e, i); - PA_LLIST_REMOVE(pa_memimport, i->pool->imports, i); - - pa_mutex_unlock(i->pool->mutex); - pa_hashmap_free(i->blocks, NULL, NULL); pa_hashmap_free(i->segments, NULL, NULL); - - pa_mutex_free(i->mutex); + PA_LLIST_REMOVE(pa_memimport, i->pool->imports, i); pa_xfree(i); } -/* Self-locked */ pa_memblock* pa_memimport_get(pa_memimport *i, uint32_t block_id, uint32_t shm_id, size_t offset, size_t size) { - pa_memblock *b = NULL; + pa_memblock *b; pa_memimport_segment *seg; assert(i); - pa_mutex_lock(i->mutex); - if (pa_hashmap_size(i->blocks) >= PA_MEMIMPORT_SLOTS_MAX) - goto finish; + return NULL; if (!(seg = pa_hashmap_get(i->segments, PA_UINT32_TO_PTR(shm_id)))) if (!(seg = segment_attach(i, shm_id))) - goto finish; + return NULL; if (offset+size > seg->memory.size) - goto finish; - + return NULL; + b = pa_xnew(pa_memblock, 1); - PA_REFCNT_INIT(b); - b->pool = i->pool; b->type = PA_MEMBLOCK_IMPORTED; b->read_only = 1; - pa_atomic_ptr_store(&b->data, (uint8_t*) seg->memory.ptr + offset); + PA_REFCNT_INIT(b); b->length = size; - pa_atomic_store(&b->n_acquired, 0); - pa_atomic_store(&b->please_signal, 0); + b->data = (uint8_t*) seg->memory.ptr + offset; + b->pool = i->pool; b->per_type.imported.id = block_id; b->per_type.imported.segment = seg; @@ -846,11 +622,7 @@ pa_memblock* pa_memimport_get(pa_memimport *i, uint32_t block_id, uint32_t shm_i seg->n_blocks++; -finish: - pa_mutex_unlock(i->mutex); - - if (b) - stat_add(b); + stat_add(b); return b; } @@ -859,15 +631,10 @@ int pa_memimport_process_revoke(pa_memimport *i, uint32_t id) { pa_memblock *b; assert(i); - pa_mutex_lock(i->mutex); - if (!(b = pa_hashmap_get(i->blocks, PA_UINT32_TO_PTR(id)))) return -1; memblock_replace_import(b); - - pa_mutex_unlock(i->mutex); - return 0; } @@ -882,84 +649,58 @@ pa_memexport* pa_memexport_new(pa_mempool *p, pa_memexport_revoke_cb_t cb, void return NULL; e = pa_xnew(pa_memexport, 1); - e->mutex = pa_mutex_new(1); e->pool = p; PA_LLIST_HEAD_INIT(struct memexport_slot, e->free_slots); PA_LLIST_HEAD_INIT(struct memexport_slot, e->used_slots); e->n_init = 0; e->revoke_cb = cb; e->userdata = userdata; - - pa_mutex_lock(p->mutex); - PA_LLIST_PREPEND(pa_memexport, p->exports, e); - pa_mutex_unlock(p->mutex); + PA_LLIST_PREPEND(pa_memexport, p->exports, e); return e; } void pa_memexport_free(pa_memexport *e) { assert(e); - pa_mutex_lock(e->mutex); while (e->used_slots) pa_memexport_process_release(e, e->used_slots - e->slots); - pa_mutex_unlock(e->mutex); - pa_mutex_lock(e->pool->mutex); PA_LLIST_REMOVE(pa_memexport, e->pool->exports, e); - pa_mutex_unlock(e->pool->mutex); - pa_xfree(e); } -/* Self-locked */ int pa_memexport_process_release(pa_memexport *e, uint32_t id) { - pa_memblock *b; - assert(e); - pa_mutex_lock(e->mutex); - if (id >= e->n_init) - goto fail; + return -1; if (!e->slots[id].block) - goto fail; - - b = e->slots[id].block; - e->slots[id].block = NULL; - - PA_LLIST_REMOVE(struct memexport_slot, e->used_slots, &e->slots[id]); - PA_LLIST_PREPEND(struct memexport_slot, e->free_slots, &e->slots[id]); + return -1; - pa_mutex_unlock(e->mutex); - /* pa_log("Processing release for %u", id); */ - assert(pa_atomic_load(&e->pool->stat.n_exported) > 0); - assert(pa_atomic_load(&e->pool->stat.exported_size) >= (int) b->length); + assert(AO_load_acquire_read(&e->pool->stat.n_exported) > 0); + assert(AO_load_acquire_read(&e->pool->stat.exported_size) >= (AO_t) e->slots[id].block->length); - pa_atomic_dec(&e->pool->stat.n_exported); - pa_atomic_add(&e->pool->stat.exported_size, (int) -b->length); + AO_fetch_and_sub1_release_write(&e->pool->stat.n_exported); + AO_fetch_and_add_release_write(&e->pool->stat.exported_size, (AO_t) -e->slots[id].block->length); - pa_memblock_unref(b); + pa_memblock_unref(e->slots[id].block); + e->slots[id].block = NULL; - return 0; + PA_LLIST_REMOVE(struct memexport_slot, e->used_slots, &e->slots[id]); + PA_LLIST_PREPEND(struct memexport_slot, e->free_slots, &e->slots[id]); -fail: - pa_mutex_unlock(e->mutex); - - return -1; + return 0; } -/* Self-locked */ static void memexport_revoke_blocks(pa_memexport *e, pa_memimport *i) { struct memexport_slot *slot, *next; assert(e); assert(i); - pa_mutex_lock(e->mutex); - for (slot = e->used_slots; slot; slot = next) { uint32_t idx; next = slot->next; @@ -972,11 +713,8 @@ static void memexport_revoke_blocks(pa_memexport *e, pa_memimport *i) { e->revoke_cb(e, idx, e->userdata); pa_memexport_process_release(e, idx); } - - pa_mutex_unlock(e->mutex); } -/* No lock necessary */ static pa_memblock *memblock_shared_copy(pa_mempool *p, pa_memblock *b) { pa_memblock *n; @@ -993,16 +731,13 @@ static pa_memblock *memblock_shared_copy(pa_mempool *p, pa_memblock *b) { if (!(n = pa_memblock_new_pool(p, b->length))) return NULL; - memcpy(pa_atomic_ptr_load(&n->data), pa_atomic_ptr_load(&b->data), b->length); + memcpy(n->data, b->data, b->length); return n; } -/* Self-locked */ int pa_memexport_put(pa_memexport *e, pa_memblock *b, uint32_t *block_id, uint32_t *shm_id, size_t *offset, size_t * size) { pa_shm *memory; struct memexport_slot *slot; - void *data; - size_t length; assert(e); assert(b); @@ -1015,15 +750,12 @@ int pa_memexport_put(pa_memexport *e, pa_memblock *b, uint32_t *block_id, uint32 if (!(b = memblock_shared_copy(e->pool, b))) return -1; - pa_mutex_lock(e->mutex); - if (e->free_slots) { slot = e->free_slots; PA_LLIST_REMOVE(struct memexport_slot, e->free_slots, slot); - } else if (e->n_init < PA_MEMEXPORT_SLOTS_MAX) + } else if (e->n_init < PA_MEMEXPORT_SLOTS_MAX) { slot = &e->slots[e->n_init++]; - else { - pa_mutex_unlock(e->mutex); + } else { pa_memblock_unref(b); return -1; } @@ -1032,11 +764,8 @@ int pa_memexport_put(pa_memexport *e, pa_memblock *b, uint32_t *block_id, uint32 slot->block = b; *block_id = slot - e->slots; - pa_mutex_unlock(e->mutex); /* pa_log("Got block id %u", *block_id); */ - data = pa_memblock_acquire(b); - if (b->type == PA_MEMBLOCK_IMPORTED) { assert(b->per_type.imported.segment); memory = &b->per_type.imported.segment->memory; @@ -1046,17 +775,15 @@ int pa_memexport_put(pa_memexport *e, pa_memblock *b, uint32_t *block_id, uint32 memory = &b->pool->memory; } - assert(data >= memory->ptr); - assert((uint8_t*) data + length <= (uint8_t*) memory->ptr + memory->size); + assert(b->data >= memory->ptr); + assert((uint8_t*) b->data + b->length <= (uint8_t*) memory->ptr + memory->size); *shm_id = memory->id; - *offset = (uint8_t*) data - (uint8_t*) memory->ptr; - *size = length; + *offset = (uint8_t*) b->data - (uint8_t*) memory->ptr; + *size = b->length; - pa_memblock_release(b); - - pa_atomic_inc(&e->pool->stat.n_exported); - pa_atomic_add(&e->pool->stat.exported_size, (int) length); + AO_fetch_and_add1_release_write(&e->pool->stat.n_exported); + AO_fetch_and_add_release_write(&e->pool->stat.exported_size, (AO_t) b->length); return 0; } diff --git a/src/pulsecore/memblock.h b/src/pulsecore/memblock.h index 9937818f..d4f2b7aa 100644 --- a/src/pulsecore/memblock.h +++ b/src/pulsecore/memblock.h @@ -25,7 +25,6 @@ #include <sys/types.h> #include <inttypes.h> -#include <pulse/def.h> #include <pulsecore/llist.h> #include <pulsecore/refcnt.h> @@ -55,25 +54,45 @@ typedef struct pa_memexport pa_memexport; typedef void (*pa_memimport_release_cb_t)(pa_memimport *i, uint32_t block_id, void *userdata); typedef void (*pa_memexport_revoke_cb_t)(pa_memexport *e, uint32_t block_id, void *userdata); +struct pa_memblock { + pa_memblock_type_t type; + int read_only; /* boolean */ + PA_REFCNT_DECLARE; /* the reference counter */ + size_t length; + void *data; + pa_mempool *pool; + + union { + struct { + void (*free_cb)(void *p); /* If type == PA_MEMBLOCK_USER this points to a function for freeing this memory block */ + } user; + + struct { + uint32_t id; + pa_memimport_segment *segment; + } imported; + } per_type; +}; + /* Please note that updates to this structure are not locked, * i.e. n_allocated might be updated at a point in time where * n_accumulated is not yet. Take these values with a grain of salt, - * they are here for purely statistical reasons.*/ + * threy are here for purely statistical reasons.*/ struct pa_mempool_stat { - pa_atomic_int_t n_allocated; - pa_atomic_int_t n_accumulated; - pa_atomic_int_t n_imported; - pa_atomic_int_t n_exported; - pa_atomic_int_t allocated_size; - pa_atomic_int_t accumulated_size; - pa_atomic_int_t imported_size; - pa_atomic_int_t exported_size; - - pa_atomic_int_t n_too_large_for_pool; - pa_atomic_int_t n_pool_full; - - pa_atomic_int_t n_allocated_by_type[PA_MEMBLOCK_TYPE_MAX]; - pa_atomic_int_t n_accumulated_by_type[PA_MEMBLOCK_TYPE_MAX]; + AO_t n_allocated; + AO_t n_accumulated; + AO_t n_imported; + AO_t n_exported; + AO_t allocated_size; + AO_t accumulated_size; + AO_t imported_size; + AO_t exported_size; + + AO_t n_too_large_for_pool; + AO_t n_pool_full; + + AO_t n_allocated_by_type[PA_MEMBLOCK_TYPE_MAX]; + AO_t n_accumulated_by_type[PA_MEMBLOCK_TYPE_MAX]; }; /* Allocate a new memory block of type PA_MEMBLOCK_MEMPOOL or PA_MEMBLOCK_APPENDED, depending on the size */ @@ -97,17 +116,9 @@ pa_memblock* pa_memblock_ref(pa_memblock*b); /* This special unref function has to be called by the owner of the memory of a static memory block when he wants to release all references to the memory. This causes the memory to be copied and -converted into a pool or malloc'ed memory block. Please note that this -function is not multiple caller safe, i.e. needs to be locked -manually if called from more than one thread at the same time. */ +converted into a PA_MEMBLOCK_DYNAMIC type memory block */ void pa_memblock_unref_fixed(pa_memblock*b); -int pa_memblock_is_read_only(pa_memblock *b); -void* pa_memblock_acquire(pa_memblock *b); -void pa_memblock_release(pa_memblock *b); -size_t pa_memblock_get_length(pa_memblock *b); -pa_mempool * pa_memblock_get_pool(pa_memblock *b); - /* The memory block manager */ pa_mempool* pa_mempool_new(int shared); void pa_mempool_free(pa_mempool *p); diff --git a/src/pulsecore/memblockq.c b/src/pulsecore/memblockq.c index dab44dc3..e6b73fc5 100644 --- a/src/pulsecore/memblockq.c +++ b/src/pulsecore/memblockq.c @@ -176,7 +176,7 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { assert(uchunk); assert(uchunk->memblock); assert(uchunk->length > 0); - assert(uchunk->index + uchunk->length <= pa_memblock_get_length(uchunk->memblock)); + assert(uchunk->index + uchunk->length <= uchunk->memblock->length); if (uchunk->length % bq->base) return -1; @@ -360,8 +360,8 @@ int pa_memblockq_peek(pa_memblockq* bq, pa_memchunk *chunk) { if (bq->silence) { chunk->memblock = pa_memblock_ref(bq->silence); - if (!length || length > pa_memblock_get_length(chunk->memblock)) - length = pa_memblock_get_length(chunk->memblock); + if (!length || length > chunk->memblock->length) + length = chunk->memblock->length; chunk->length = length; } else { @@ -413,8 +413,8 @@ void pa_memblockq_drop(pa_memblockq *bq, const pa_memchunk *chunk, size_t length if (bq->silence) { - if (!l || l > pa_memblock_get_length(bq->silence)) - l = pa_memblock_get_length(bq->silence); + if (!l || l > bq->silence->length) + l = bq->silence->length; } diff --git a/src/pulsecore/memchunk.c b/src/pulsecore/memchunk.c index 55c4bfa7..1dbad2b9 100644 --- a/src/pulsecore/memchunk.c +++ b/src/pulsecore/memchunk.c @@ -35,25 +35,22 @@ void pa_memchunk_make_writable(pa_memchunk *c, size_t min) { pa_memblock *n; size_t l; - void *tdata, *sdata; assert(c); assert(c->memblock); + assert(PA_REFCNT_VALUE(c->memblock) > 0); - if (pa_memblock_is_read_only(c->memblock) && - pa_memblock_get_length(c->memblock) >= c->index+min) + if (PA_REFCNT_VALUE(c->memblock) == 1 && + !c->memblock->read_only && + c->memblock->length >= c->index+min) return; l = c->length; if (l < min) l = min; - n = pa_memblock_new(pa_memblock_get_pool(c->memblock), l); - tdata = pa_memblock_acquire(n); - sdata = pa_memblock_acquire(c->memblock); - memcpy(tdata, (uint8_t*) sdata + c->index, c->length); - pa_memblock_release(n); - pa_memblock_release(c->memblock); + n = pa_memblock_new(c->memblock->pool, l); + memcpy(n->data, (uint8_t*) c->memblock->data + c->index, c->length); pa_memblock_unref(c->memblock); c->memblock = n; c->index = 0; diff --git a/src/pulsecore/play-memchunk.c b/src/pulsecore/play-memchunk.c index b711c98c..cde6a9ee 100644 --- a/src/pulsecore/play-memchunk.c +++ b/src/pulsecore/play-memchunk.c @@ -55,7 +55,7 @@ static int sink_input_peek(pa_sink_input *i, pa_memchunk *chunk) { if (c->length <= 0) return -1; - assert(c->memblock); + assert(c->memblock && c->memblock->length); *chunk = *c; pa_memblock_ref(c->memblock); diff --git a/src/pulsecore/protocol-esound.c b/src/pulsecore/protocol-esound.c index 65b93eb4..80aeb27b 100644 --- a/src/pulsecore/protocol-esound.c +++ b/src/pulsecore/protocol-esound.c @@ -891,22 +891,14 @@ static int do_read(struct connection *c) { } } else if (c->state == ESD_CACHING_SAMPLE) { ssize_t r; - void *p; - assert(c->scache.memchunk.memblock); - assert(c->scache.name); - assert(c->scache.memchunk.index < c->scache.memchunk.length); - - p = pa_memblock_acquire(c->scache.memchunk.memblock); + assert(c->scache.memchunk.memblock && c->scache.name && c->scache.memchunk.index < c->scache.memchunk.length); - if ((r = pa_iochannel_read(c->io, (uint8_t*) p+c->scache.memchunk.index, c->scache.memchunk.length-c->scache.memchunk.index)) <= 0) { - pa_memblock_release(c->scache.memchunk.memblock); + if ((r = pa_iochannel_read(c->io, (uint8_t*) c->scache.memchunk.memblock->data+c->scache.memchunk.index, c->scache.memchunk.length-c->scache.memchunk.index)) <= 0) { pa_log_debug("read(): %s", r < 0 ? pa_cstrerror(errno) : "EOF"); return -1; } - pa_memblock_release(c->scache.memchunk.memblock); - c->scache.memchunk.index += r; assert(c->scache.memchunk.index <= c->scache.memchunk.length); @@ -933,7 +925,6 @@ static int do_read(struct connection *c) { pa_memchunk chunk; ssize_t r; size_t l; - void *p; assert(c->input_memblockq); @@ -946,7 +937,7 @@ static int do_read(struct connection *c) { l = c->playback.fragment_size; if (c->playback.current_memblock) - if (pa_memblock_get_length(c->playback.current_memblock) - c->playback.memblock_index < l) { + if (c->playback.current_memblock->length - c->playback.memblock_index < l) { pa_memblock_unref(c->playback.current_memblock); c->playback.current_memblock = NULL; c->playback.memblock_index = 0; @@ -954,21 +945,15 @@ static int do_read(struct connection *c) { if (!c->playback.current_memblock) { c->playback.current_memblock = pa_memblock_new(c->protocol->core->mempool, c->playback.fragment_size*2); - assert(c->playback.current_memblock); - assert(pa_memblock_get_length(c->playback.current_memblock) >= l); + assert(c->playback.current_memblock && c->playback.current_memblock->length >= l); c->playback.memblock_index = 0; } - p = pa_memblock_acquire(c->playback.current_memblock); - - if ((r = pa_iochannel_read(c->io, (uint8_t*) p+c->playback.memblock_index, l)) <= 0) { - pa_memblock_release(c->playback.current_memblock); + if ((r = pa_iochannel_read(c->io, (uint8_t*) c->playback.current_memblock->data+c->playback.memblock_index, l)) <= 0) { pa_log_debug("read(): %s", r < 0 ? pa_cstrerror(errno) : "EOF"); return -1; } - - pa_memblock_release(c->playback.current_memblock); - + chunk.memblock = c->playback.current_memblock; chunk.index = c->playback.memblock_index; chunk.length = r; @@ -1005,26 +990,19 @@ static int do_write(struct connection *c) { } else if (c->state == ESD_STREAMING_DATA && c->source_output) { pa_memchunk chunk; ssize_t r; - void *p; assert(c->output_memblockq); if (pa_memblockq_peek(c->output_memblockq, &chunk) < 0) return 0; - assert(chunk.memblock); - assert(chunk.length); - - p = pa_memblock_acquire(chunk.memblock); + assert(chunk.memblock && chunk.length); - if ((r = pa_iochannel_write(c->io, (uint8_t*) p+chunk.index, chunk.length)) < 0) { - pa_memblock_release(chunk.memblock); + if ((r = pa_iochannel_write(c->io, (uint8_t*) chunk.memblock->data+chunk.index, chunk.length)) < 0) { pa_memblock_unref(chunk.memblock); pa_log("write(): %s", pa_cstrerror(errno)); return -1; } - pa_memblock_release(chunk.memblock); - pa_memblockq_drop(c->output_memblockq, &chunk, r); pa_memblock_unref(chunk.memblock); diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index fba611d7..38c024b7 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -2274,7 +2274,6 @@ static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t o } else { struct upload_stream *u = (struct upload_stream*) stream; size_t l; - assert(u->type == UPLOAD_STREAM); if (!u->memchunk.memblock) { @@ -2294,18 +2293,9 @@ static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t o if (l > chunk->length) l = chunk->length; - if (l > 0) { - void *src, *dst; - dst = pa_memblock_acquire(u->memchunk.memblock); - src = pa_memblock_acquire(chunk->memblock); - - memcpy((uint8_t*) dst + u->memchunk.index + u->memchunk.length, - (uint8_t*) src+chunk->index, l); - - pa_memblock_release(u->memchunk.memblock); - pa_memblock_release(chunk->memblock); - + memcpy((uint8_t*) u->memchunk.memblock->data + u->memchunk.index + u->memchunk.length, + (uint8_t*) chunk->memblock->data+chunk->index, l); u->memchunk.length += l; u->length -= l; } diff --git a/src/pulsecore/protocol-simple.c b/src/pulsecore/protocol-simple.c index bf203e42..6bfba875 100644 --- a/src/pulsecore/protocol-simple.c +++ b/src/pulsecore/protocol-simple.c @@ -113,7 +113,6 @@ static int do_read(struct connection *c) { pa_memchunk chunk; ssize_t r; size_t l; - void *p; if (!c->sink_input || !(l = pa_memblockq_missing(c->input_memblockq))) return 0; @@ -122,7 +121,7 @@ static int do_read(struct connection *c) { l = c->playback.fragment_size; if (c->playback.current_memblock) - if (pa_memblock_get_length(c->playback.current_memblock) - c->playback.memblock_index < l) { + if (c->playback.current_memblock->length - c->playback.memblock_index < l) { pa_memblock_unref(c->playback.current_memblock); c->playback.current_memblock = NULL; c->playback.memblock_index = 0; @@ -130,20 +129,15 @@ static int do_read(struct connection *c) { if (!c->playback.current_memblock) { c->playback.current_memblock = pa_memblock_new(c->protocol->core->mempool, c->playback.fragment_size*2); - assert(c->playback.current_memblock); - assert(pa_memblock_get_length(c->playback.current_memblock) >= l); + assert(c->playback.current_memblock && c->playback.current_memblock->length >= l); c->playback.memblock_index = 0; } - - p = pa_memblock_acquire(c->playback.current_memblock); - if ((r = pa_iochannel_read(c->io, (uint8_t*) p + c->playback.memblock_index, l)) <= 0) { - pa_memblock_release(c->playback.current_memblock); + if ((r = pa_iochannel_read(c->io, (uint8_t*) c->playback.current_memblock->data+c->playback.memblock_index, l)) <= 0) { pa_log_debug("read(): %s", r == 0 ? "EOF" : pa_cstrerror(errno)); return -1; } - pa_memblock_release(c->playback.current_memblock); chunk.memblock = c->playback.current_memblock; chunk.index = c->playback.memblock_index; chunk.length = r; @@ -162,8 +156,7 @@ static int do_read(struct connection *c) { static int do_write(struct connection *c) { pa_memchunk chunk; ssize_t r; - void *p; - + if (!c->source_output) return 0; @@ -172,17 +165,12 @@ static int do_write(struct connection *c) { return 0; assert(chunk.memblock && chunk.length); - - p = pa_memblock_acquire(chunk.memblock); - if ((r = pa_iochannel_write(c->io, (uint8_t*) p+chunk.index, chunk.length)) < 0) { - pa_memblock_release(chunk.memblock); + if ((r = pa_iochannel_write(c->io, (uint8_t*) chunk.memblock->data+chunk.index, chunk.length)) < 0) { pa_memblock_unref(chunk.memblock); pa_log("write(): %s", pa_cstrerror(errno)); return -1; } - - pa_memblock_release(chunk.memblock); pa_memblockq_drop(c->output_memblockq, &chunk, r); pa_memblock_unref(chunk.memblock); diff --git a/src/pulsecore/pstream.c b/src/pulsecore/pstream.c index 33963796..566fb060 100644 --- a/src/pulsecore/pstream.c +++ b/src/pulsecore/pstream.c @@ -48,7 +48,6 @@ #include <pulsecore/creds.h> #include <pulsecore/mutex.h> #include <pulsecore/refcnt.h> -#include <pulsecore/anotify.h> #include "pstream.h" @@ -114,11 +113,10 @@ struct pa_pstream { PA_REFCNT_DECLARE; pa_mainloop_api *mainloop; + pa_defer_event *defer_event; pa_iochannel *io; - pa_queue *send_queue; - pa_mutex *mutex; /* only for access to the queue */ - pa_anotify *anotify; + pa_mutex *mutex; int dead; @@ -128,7 +126,6 @@ struct pa_pstream { uint32_t shm_info[PA_PSTREAM_SHM_MAX]; void *data; size_t index; - pa_memchunk memchunk; } write; struct { @@ -173,6 +170,10 @@ static void do_something(pa_pstream *p) { pa_pstream_ref(p); + pa_mutex_lock(p->mutex); + + p->mainloop->defer_enable(p->defer_event, 0); + if (!p->dead && pa_iochannel_is_readable(p->io)) { if (do_read(p) < 0) goto fail; @@ -184,6 +185,8 @@ static void do_something(pa_pstream *p) { goto fail; } + pa_mutex_unlock(p->mutex); + pa_pstream_unref(p); return; @@ -194,6 +197,8 @@ fail: if (p->die_callback) p->die_callback(p, p->die_callback_userdata); + pa_mutex_unlock(p->mutex); + pa_pstream_unref(p); } @@ -206,10 +211,13 @@ static void io_callback(pa_iochannel*io, void *userdata) { do_something(p); } -static void anotify_callback(uint8_t event, void *userdata) { +static void defer_callback(pa_mainloop_api *m, pa_defer_event *e, void*userdata) { pa_pstream *p = userdata; assert(p); + assert(p->defer_event == e); + assert(p->mainloop == m); + do_something(p); } @@ -229,16 +237,16 @@ pa_pstream *pa_pstream_new(pa_mainloop_api *m, pa_iochannel *io, pa_mempool *poo p->dead = 0; p->mutex = pa_mutex_new(1); - p->anotify = pa_anotify_new(m, anotify_callback, p); p->mainloop = m; + p->defer_event = m->defer_new(m, defer_callback, p); + m->defer_enable(p->defer_event, 0); p->send_queue = pa_queue_new(); assert(p->send_queue); p->write.current = NULL; p->write.index = 0; - pa_memchunk_reset(&p->write.memchunk); p->read.memblock = NULL; p->read.packet = NULL; p->read.index = 0; @@ -301,15 +309,9 @@ static void pstream_free(pa_pstream *p) { if (p->read.packet) pa_packet_unref(p->read.packet); - if (p->write.memchunk.memblock) - pa_memblock_unref(p->write.memchunk.memblock); - if (p->mutex) pa_mutex_free(p->mutex); - if (p->anotify) - pa_anotify_free(p->anotify); - pa_xfree(p); } @@ -320,6 +322,11 @@ void pa_pstream_send_packet(pa_pstream*p, pa_packet *packet, const pa_creds *cre assert(PA_REFCNT_VALUE(p) > 0); assert(packet); + pa_mutex_lock(p->mutex); + + if (p->dead) + goto finish; + i = pa_xnew(struct item_info, 1); i->type = PA_PSTREAM_ITEM_PACKET; i->packet = pa_packet_ref(packet); @@ -329,11 +336,12 @@ void pa_pstream_send_packet(pa_pstream*p, pa_packet *packet, const pa_creds *cre i->creds = *creds; #endif - pa_mutex_lock(p->mutex); pa_queue_push(p->send_queue, i); + p->mainloop->defer_enable(p->defer_event, 1); + +finish: + pa_mutex_unlock(p->mutex); - - pa_anotify_signal(p->anotify, 0); } void pa_pstream_send_memblock(pa_pstream*p, uint32_t channel, int64_t offset, pa_seek_mode_t seek_mode, const pa_memchunk *chunk) { @@ -344,6 +352,12 @@ void pa_pstream_send_memblock(pa_pstream*p, uint32_t channel, int64_t offset, pa assert(channel != (uint32_t) -1); assert(chunk); + pa_mutex_lock(p->mutex); + + if (p->dead) + goto finish; + + length = chunk->length; idx = 0; while (length > 0) { @@ -365,15 +379,17 @@ void pa_pstream_send_memblock(pa_pstream*p, uint32_t channel, int64_t offset, pa i->with_creds = 0; #endif - pa_mutex_lock(p->mutex); pa_queue_push(p->send_queue, i); - pa_mutex_unlock(p->mutex); idx += n; length -= n; } + + p->mainloop->defer_enable(p->defer_event, 1); - pa_anotify_signal(p->anotify, 0); +finish: + + pa_mutex_unlock(p->mutex); } static void memimport_release_cb(pa_memimport *i, uint32_t block_id, void *userdata) { @@ -383,6 +399,11 @@ static void memimport_release_cb(pa_memimport *i, uint32_t block_id, void *userd assert(p); assert(PA_REFCNT_VALUE(p) > 0); + pa_mutex_lock(p->mutex); + + if (p->dead) + goto finish; + /* pa_log("Releasing block %u", block_id); */ item = pa_xnew(struct item_info, 1); @@ -392,11 +413,12 @@ static void memimport_release_cb(pa_memimport *i, uint32_t block_id, void *userd item->with_creds = 0; #endif - pa_mutex_lock(p->mutex); pa_queue_push(p->send_queue, item); - pa_mutex_unlock(p->mutex); + p->mainloop->defer_enable(p->defer_event, 1); - pa_anotify_signal(p->anotify, 0); +finish: + + pa_mutex_unlock(p->mutex); } static void memexport_revoke_cb(pa_memexport *e, uint32_t block_id, void *userdata) { @@ -406,6 +428,11 @@ static void memexport_revoke_cb(pa_memexport *e, uint32_t block_id, void *userda assert(p); assert(PA_REFCNT_VALUE(p) > 0); + pa_mutex_lock(p->mutex); + + if (p->dead) + goto finish; + /* pa_log("Revoking block %u", block_id); */ item = pa_xnew(struct item_info, 1); @@ -415,27 +442,23 @@ static void memexport_revoke_cb(pa_memexport *e, uint32_t block_id, void *userda item->with_creds = 0; #endif - pa_mutex_lock(p->mutex); pa_queue_push(p->send_queue, item); - pa_mutex_unlock(p->mutex); + p->mainloop->defer_enable(p->defer_event, 1); - pa_anotify_signal(p->anotify, 0); +finish: + + pa_mutex_unlock(p->mutex); } static void prepare_next_write_item(pa_pstream *p) { assert(p); assert(PA_REFCNT_VALUE(p) > 0); - pa_mutex_lock(p->mutex); - p->write.current = pa_queue_pop(p->send_queue); - pa_mutex_unlock(p->mutex); - - if (!p->write.current) + if (!(p->write.current = pa_queue_pop(p->send_queue))) return; p->write.index = 0; p->write.data = NULL; - pa_memchunk_reset(&p->write.memchunk); p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH] = 0; p->write.descriptor[PA_PSTREAM_DESCRIPTOR_CHANNEL] = htonl((uint32_t) -1); @@ -502,9 +525,7 @@ static void prepare_next_write_item(pa_pstream *p) { if (send_payload) { p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH] = htonl(p->write.current->chunk.length); - p->write.memchunk = p->write.current->chunk; - pa_memblock_ref(p->write.memchunk.memblock); - p->write.data = NULL; + p->write.data = (uint8_t*) p->write.current->chunk.memblock->data + p->write.current->chunk.index; } p->write.descriptor[PA_PSTREAM_DESCRIPTOR_FLAGS] = htonl(flags); @@ -520,7 +541,6 @@ static int do_write(pa_pstream *p) { void *d; size_t l; ssize_t r; - pa_memblock *release_memblock = NULL; assert(p); assert(PA_REFCNT_VALUE(p) > 0); @@ -535,16 +555,9 @@ static int do_write(pa_pstream *p) { d = (uint8_t*) p->write.descriptor + p->write.index; l = PA_PSTREAM_DESCRIPTOR_SIZE - p->write.index; } else { - assert(p->write.data || p->write.memchunk.memblock); - - if (p->write.data) - d = p->write.data; - else { - d = (uint8_t*) pa_memblock_acquire(p->write.memchunk.memblock) + p->write.memchunk.index; - release_memblock = p->write.memchunk.memblock; - } + assert(p->write.data); - d = (uint8_t*) d + p->write.index - PA_PSTREAM_DESCRIPTOR_SIZE; + d = (uint8_t*) p->write.data + p->write.index - PA_PSTREAM_DESCRIPTOR_SIZE; l = ntohl(p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH]) - (p->write.index - PA_PSTREAM_DESCRIPTOR_SIZE); } @@ -554,17 +567,14 @@ static int do_write(pa_pstream *p) { if (p->send_creds_now) { if ((r = pa_iochannel_write_with_creds(p->io, d, l, &p->write_creds)) < 0) - goto fail; + return -1; p->send_creds_now = 0; } else #endif if ((r = pa_iochannel_write(p->io, d, l)) < 0) - goto fail; - - if (release_memblock) - pa_memblock_release(release_memblock); + return -1; p->write.index += r; @@ -578,20 +588,12 @@ static int do_write(pa_pstream *p) { } return 0; - -fail: - - if (release_memblock) - pa_memblock_release(release_memblock); - - return -1; } static int do_read(pa_pstream *p) { void *d; size_t l; ssize_t r; - pa_memblock *release_memblock = NULL; assert(p); assert(PA_REFCNT_VALUE(p) > 0); @@ -600,16 +602,8 @@ static int do_read(pa_pstream *p) { d = (uint8_t*) p->read.descriptor + p->read.index; l = PA_PSTREAM_DESCRIPTOR_SIZE - p->read.index; } else { - assert(p->read.data || p->read.memblock); - - if (p->read.data) - d = p->read.data; - else { - d = pa_memblock_acquire(p->read.memblock); - release_memblock = p->read.memblock; - } - - d = (uint8_t*) d + p->read.index - PA_PSTREAM_DESCRIPTOR_SIZE; + assert(p->read.data); + d = (uint8_t*) p->read.data + p->read.index - PA_PSTREAM_DESCRIPTOR_SIZE; l = ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH]) - (p->read.index - PA_PSTREAM_DESCRIPTOR_SIZE); } @@ -618,17 +612,14 @@ static int do_read(pa_pstream *p) { int b = 0; if ((r = pa_iochannel_read_with_creds(p->io, d, l, &p->read_creds, &b)) <= 0) - goto fail; + return -1; p->read_creds_valid = p->read_creds_valid || b; } #else if ((r = pa_iochannel_read(p->io, d, l)) <= 0) - goto fail; + return -1; #endif - - if (release_memblock) - pa_memblock_release(release_memblock); p->read.index += r; @@ -710,7 +701,7 @@ static int do_read(pa_pstream *p) { /* Frame is a memblock frame */ p->read.memblock = pa_memblock_new(p->mempool, length); - p->read.data = NULL; + p->read.data = p->read.memblock->data; } else { pa_log_warn("Recieved memblock frame with invalid flags value."); @@ -797,7 +788,7 @@ static int do_read(pa_pstream *p) { chunk.memblock = b; chunk.index = 0; - chunk.length = pa_memblock_get_length(b); + chunk.length = b->length; offset = (int64_t) ( (((uint64_t) ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_HI])) << 32) | @@ -825,51 +816,52 @@ frame_done: p->read.memblock = NULL; p->read.packet = NULL; p->read.index = 0; - p->read.data = NULL; #ifdef HAVE_CREDS p->read_creds_valid = 0; #endif return 0; - -fail: - if (release_memblock) - pa_memblock_release(release_memblock); - - return -1; } void pa_pstream_set_die_callback(pa_pstream *p, pa_pstream_notify_cb_t cb, void *userdata) { assert(p); assert(PA_REFCNT_VALUE(p) > 0); + pa_mutex_lock(p->mutex); p->die_callback = cb; p->die_callback_userdata = userdata; + pa_mutex_unlock(p->mutex); } void pa_pstream_set_drain_callback(pa_pstream *p, pa_pstream_notify_cb_t cb, void *userdata) { assert(p); assert(PA_REFCNT_VALUE(p) > 0); + pa_mutex_lock(p->mutex); p->drain_callback = cb; p->drain_callback_userdata = userdata; + pa_mutex_unlock(p->mutex); } void pa_pstream_set_recieve_packet_callback(pa_pstream *p, pa_pstream_packet_cb_t cb, void *userdata) { assert(p); assert(PA_REFCNT_VALUE(p) > 0); + pa_mutex_lock(p->mutex); p->recieve_packet_callback = cb; p->recieve_packet_callback_userdata = userdata; + pa_mutex_unlock(p->mutex); } void pa_pstream_set_recieve_memblock_callback(pa_pstream *p, pa_pstream_memblock_cb_t cb, void *userdata) { assert(p); assert(PA_REFCNT_VALUE(p) > 0); + pa_mutex_lock(p->mutex); p->recieve_memblock_callback = cb; p->recieve_memblock_callback_userdata = userdata; + pa_mutex_unlock(p->mutex); } int pa_pstream_is_pending(pa_pstream *p) { @@ -909,6 +901,8 @@ pa_pstream* pa_pstream_ref(pa_pstream*p) { void pa_pstream_close(pa_pstream *p) { assert(p); + pa_mutex_lock(p->mutex); + p->dead = 1; if (p->import) { @@ -926,16 +920,25 @@ void pa_pstream_close(pa_pstream *p) { p->io = NULL; } + if (p->defer_event) { + p->mainloop->defer_free(p->defer_event); + p->defer_event = NULL; + } + p->die_callback = NULL; p->drain_callback = NULL; p->recieve_packet_callback = NULL; p->recieve_memblock_callback = NULL; + + pa_mutex_unlock(p->mutex); } void pa_pstream_use_shm(pa_pstream *p, int enable) { assert(p); assert(PA_REFCNT_VALUE(p) > 0); + pa_mutex_lock(p->mutex); + p->use_shm = enable; if (enable) { @@ -950,4 +953,6 @@ void pa_pstream_use_shm(pa_pstream *p, int enable) { p->export = NULL; } } + + pa_mutex_unlock(p->mutex); } diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c index c28c2fb3..b0142049 100644 --- a/src/pulsecore/resampler.c +++ b/src/pulsecore/resampler.c @@ -51,7 +51,8 @@ struct pa_resampler { }; struct impl_libsamplerate { - pa_memchunk buf1, buf2, buf3, buf4; + pa_memblock *buf1_block, *buf2_block, *buf3_block, *buf4_block; + float* buf1, *buf2, *buf3, *buf4; unsigned buf1_samples, buf2_samples, buf3_samples, buf4_samples; pa_convert_to_float32ne_func_t to_float32ne_func; @@ -223,14 +224,14 @@ static void libsamplerate_free(pa_resampler *r) { if (u->src_state) src_delete(u->src_state); - if (u->buf1.memblock) - pa_memblock_unref(u->buf1.memblock); - if (u->buf2.memblock) - pa_memblock_unref(u->buf2.memblock); - if (u->buf3.memblock) - pa_memblock_unref(u->buf3.memblock); - if (u->buf4.memblock) - pa_memblock_unref(u->buf4.memblock); + if (u->buf1_block) + pa_memblock_unref(u->buf1_block); + if (u->buf2_block) + pa_memblock_unref(u->buf2_block); + if (u->buf3_block) + pa_memblock_unref(u->buf3_block); + if (u->buf4_block) + pa_memblock_unref(u->buf4_block); pa_xfree(u); } @@ -269,80 +270,64 @@ static void calc_map_table(pa_resampler *r) { } } -static pa_memchunk* convert_to_float(pa_resampler *r, pa_memchunk *input) { +static float * convert_to_float(pa_resampler *r, void *input, unsigned n_frames) { struct impl_libsamplerate *u; unsigned n_samples; - void *src, *dst; assert(r); assert(input); - assert(input->memblock); - assert(r->impl_data); u = r->impl_data; /* Convert the incoming sample into floats and place them in buf1 */ - if (!u->to_float32ne_func || !input->length) + if (!u->to_float32ne_func) return input; - n_samples = (input->length / r->i_fz) * r->i_ss.channels; + n_samples = n_frames * r->i_ss.channels; - if (!u->buf1.memblock || u->buf1_samples < n_samples) { - if (u->buf1.memblock) - pa_memblock_unref(u->buf1.memblock); + if (u->buf1_samples < n_samples) { + if (u->buf1_block) + pa_memblock_unref(u->buf1_block); u->buf1_samples = n_samples; - u->buf1.memblock = pa_memblock_new(r->mempool, u->buf1.length = sizeof(float) * n_samples); - u->buf1.index = 0; + u->buf1_block = pa_memblock_new(r->mempool, sizeof(float) * n_samples); + u->buf1 = u->buf1_block->data; } + + u->to_float32ne_func(n_samples, input, u->buf1); - src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index; - dst = (uint8_t*) pa_memblock_acquire(u->buf1.memblock); - u->to_float32ne_func(n_samples, src, dst); - pa_memblock_release(input->memblock); - pa_memblock_release(u->buf1.memblock); - - u->buf1.length = sizeof(float) * n_samples; - - return &u->buf1; + return u->buf1; } -static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) { +static float *remap_channels(pa_resampler *r, float *input, unsigned n_frames) { struct impl_libsamplerate *u; - unsigned n_samples, n_frames; + unsigned n_samples; int i_skip, o_skip; unsigned oc; - float *src, *dst; assert(r); assert(input); - assert(input->memblock); - assert(r->impl_data); u = r->impl_data; /* Remap channels and place the result int buf2 */ - if (!u->map_required || !input->length) + if (!u->map_required) return input; - n_samples = input->length / sizeof(float); - n_frames = n_samples / r->o_ss.channels; + n_samples = n_frames * r->o_ss.channels; - if (!u->buf2.memblock || u->buf2_samples < n_samples) { - if (u->buf2.memblock) - pa_memblock_unref(u->buf2.memblock); + if (u->buf2_samples < n_samples) { + if (u->buf2_block) + pa_memblock_unref(u->buf2_block); u->buf2_samples = n_samples; - u->buf2.memblock = pa_memblock_new(r->mempool, u->buf2.length = sizeof(float) * n_samples); - u->buf2.index = 0; + u->buf2_block = pa_memblock_new(r->mempool, sizeof(float) * n_samples); + u->buf2 = u->buf2_block->data; } - src = (float*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index); - dst = (float*) pa_memblock_acquire(u->buf2.memblock); - - memset(dst, 0, n_samples * sizeof(float)); + memset(u->buf2, 0, n_samples * sizeof(float)); o_skip = sizeof(float) * r->o_ss.channels; i_skip = sizeof(float) * r->i_ss.channels; @@ -353,57 +338,49 @@ static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) { for (i = 0; i < PA_CHANNELS_MAX && u->map_table[oc][i] >= 0; i++) oil_vectoradd_f32( - dst + oc, o_skip, - dst + oc, o_skip, - src + u->map_table[oc][i], i_skip, + u->buf2 + oc, o_skip, + u->buf2 + oc, o_skip, + input + u->map_table[oc][i], i_skip, n_frames, &one, &one); } - pa_memblock_release(input->memblock); - pa_memblock_release(u->buf2.memblock); - - u->buf2.length = n_frames * sizeof(float) * r->o_ss.channels; - - return &u->buf2; + return u->buf2; } -static pa_memchunk *resample(pa_resampler *r, pa_memchunk *input) { +static float *resample(pa_resampler *r, float *input, unsigned *n_frames) { struct impl_libsamplerate *u; SRC_DATA data; - unsigned in_n_frames, in_n_samples; unsigned out_n_frames, out_n_samples; int ret; assert(r); assert(input); + assert(n_frames); assert(r->impl_data); u = r->impl_data; /* Resample the data and place the result in buf3 */ - if (!u->src_state || !input->length) + if (!u->src_state) return input; - in_n_samples = input->length / sizeof(float); - in_n_frames = in_n_samples * r->o_ss.channels; - - out_n_frames = (in_n_frames*r->o_ss.rate/r->i_ss.rate)+1024; + out_n_frames = (*n_frames*r->o_ss.rate/r->i_ss.rate)+1024; out_n_samples = out_n_frames * r->o_ss.channels; - if (!u->buf3.memblock || u->buf3_samples < out_n_samples) { - if (u->buf3.memblock) - pa_memblock_unref(u->buf3.memblock); + if (u->buf3_samples < out_n_samples) { + if (u->buf3_block) + pa_memblock_unref(u->buf3_block); u->buf3_samples = out_n_samples; - u->buf3.memblock = pa_memblock_new(r->mempool, u->buf3.length = sizeof(float) * out_n_samples); - u->buf3.index = 0; + u->buf3_block = pa_memblock_new(r->mempool, sizeof(float) * out_n_samples); + u->buf3 = u->buf3_block->data; } - data.data_in = (float*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index); - data.input_frames = in_n_frames; + data.data_in = input; + data.input_frames = *n_frames; - data.data_out = (float*) pa_memblock_acquire(u->buf3.memblock); + data.data_out = u->buf3; data.output_frames = out_n_frames; data.src_ratio = (double) r->o_ss.rate / r->i_ss.rate; @@ -411,20 +388,16 @@ static pa_memchunk *resample(pa_resampler *r, pa_memchunk *input) { ret = src_process(u->src_state, &data); assert(ret == 0); - assert((unsigned) data.input_frames_used == in_n_frames); + assert((unsigned) data.input_frames_used == *n_frames); - pa_memblock_release(input->memblock); - pa_memblock_release(u->buf3.memblock); - - u->buf3.length = data.output_frames_gen * sizeof(float) * r->o_ss.channels; + *n_frames = data.output_frames_gen; - return &u->buf3; + return u->buf3; } -static pa_memchunk *convert_from_float(pa_resampler *r, pa_memchunk *input) { +static void *convert_from_float(pa_resampler *r, float *input, unsigned n_frames) { struct impl_libsamplerate *u; - unsigned n_samples, n_frames; - void *src, *dst; + unsigned n_samples; assert(r); assert(input); @@ -433,35 +406,30 @@ static pa_memchunk *convert_from_float(pa_resampler *r, pa_memchunk *input) { /* Convert the data into the correct sample type and place the result in buf4 */ - if (!u->from_float32ne_func || !input->length) + if (!u->from_float32ne_func) return input; - - n_frames = input->length / sizeof(float) / r->o_ss.channels; + n_samples = n_frames * r->o_ss.channels; if (u->buf4_samples < n_samples) { - if (u->buf4.memblock) - pa_memblock_unref(u->buf4.memblock); + if (u->buf4_block) + pa_memblock_unref(u->buf4_block); u->buf4_samples = n_samples; - u->buf4.memblock = pa_memblock_new(r->mempool, u->buf4.length = r->o_fz * n_frames); - u->buf4.index = 0; + u->buf4_block = pa_memblock_new(r->mempool, sizeof(float) * n_samples); + u->buf4 = u->buf4_block->data; } + + u->from_float32ne_func(n_samples, input, u->buf4); - src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->length; - dst = pa_memblock_acquire(u->buf4.memblock); - u->from_float32ne_func(n_samples, src, dst); - pa_memblock_release(input->memblock); - pa_memblock_release(u->buf4.memblock); - - u->buf4.length = r->o_fz * n_frames; - - return &u->buf4; + return u->buf4; } static void libsamplerate_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out) { struct impl_libsamplerate *u; - pa_memchunk *buf; + float *buf; + void *input, *output; + unsigned n_frames; assert(r); assert(in); @@ -473,23 +441,55 @@ static void libsamplerate_run(pa_resampler *r, const pa_memchunk *in, pa_memchun u = r->impl_data; - buf = convert_to_float(r, (pa_memchunk*) in); - buf = remap_channels(r, buf); - buf = resample(r, buf); - - if (buf->length) { - buf = convert_from_float(r, buf); - *out = *buf; - - if (buf == in) - pa_memblock_ref(buf->memblock); - else - pa_memchunk_reset(buf); - } else - pa_memchunk_reset(out); - - pa_memblock_release(in->memblock); - + input = ((uint8_t*) in->memblock->data + in->index); + n_frames = in->length / r->i_fz; + assert(n_frames > 0); + + buf = convert_to_float(r, input, n_frames); + buf = remap_channels(r, buf, n_frames); + buf = resample(r, buf, &n_frames); + + if (n_frames) { + output = convert_from_float(r, buf, n_frames); + + if (output == input) { + /* Mm, no adjustment has been necessary, so let's return the original block */ + out->memblock = pa_memblock_ref(in->memblock); + out->index = in->index; + out->length = in->length; + } else { + out->length = n_frames * r->o_fz; + out->index = 0; + out->memblock = NULL; + + if (output == u->buf1) { + u->buf1 = NULL; + u->buf1_samples = 0; + out->memblock = u->buf1_block; + u->buf1_block = NULL; + } else if (output == u->buf2) { + u->buf2 = NULL; + u->buf2_samples = 0; + out->memblock = u->buf2_block; + u->buf2_block = NULL; + } else if (output == u->buf3) { + u->buf3 = NULL; + u->buf3_samples = 0; + out->memblock = u->buf3_block; + u->buf3_block = NULL; + } else if (output == u->buf4) { + u->buf4 = NULL; + u->buf4_samples = 0; + out->memblock = u->buf4_block; + u->buf4_block = NULL; + } + + assert(out->memblock); + } + } else { + out->memblock = NULL; + out->index = out->length = 0; + } } static void libsamplerate_update_input_rate(pa_resampler *r, uint32_t rate) { @@ -516,10 +516,8 @@ static int libsamplerate_init(pa_resampler *r) { r->impl_data = u = pa_xnew(struct impl_libsamplerate, 1); - pa_memchunk_reset(&u->buf1); - pa_memchunk_reset(&u->buf2); - pa_memchunk_reset(&u->buf3); - pa_memchunk_reset(&u->buf4); + u->buf1 = u->buf2 = u->buf3 = u->buf4 = NULL; + u->buf1_block = u->buf2_block = u->buf3_block = u->buf4_block = NULL; u->buf1_samples = u->buf2_samples = u->buf3_samples = u->buf4_samples = 0; if (r->i_ss.format == PA_SAMPLE_FLOAT32NE) @@ -580,16 +578,12 @@ static void trivial_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out /* Do real resampling */ size_t l; unsigned o_index; - void *src, *dst; /* The length of the new memory block rounded up */ l = ((((n_frames+1) * r->o_ss.rate) / r->i_ss.rate) + 1) * fz; out->index = 0; out->memblock = pa_memblock_new(r->mempool, l); - - src = (uint8_t*) pa_memblock_acquire(in->memblock) + in->index; - dst = pa_memblock_acquire(out->memblock); for (o_index = 0;; o_index++, u->o_counter++) { unsigned j; @@ -600,16 +594,13 @@ static void trivial_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out if (j >= n_frames) break; - assert(o_index*fz < pa_memblock_get_length(out->memblock)); + assert(o_index*fz < out->memblock->length); - memcpy((uint8_t*) dst + fz*o_index, - (uint8_t*) src + fz*j, fz); + memcpy((uint8_t*) out->memblock->data + fz*o_index, + (uint8_t*) in->memblock->data + in->index + fz*j, fz); } - - pa_memblock_release(in->memblock); - pa_memblock_release(out->memblock); - + out->length = o_index*fz; } diff --git a/src/pulsecore/sample-util.c b/src/pulsecore/sample-util.c index 52023d31..d902b4b5 100644 --- a/src/pulsecore/sample-util.c +++ b/src/pulsecore/sample-util.c @@ -46,27 +46,15 @@ pa_memblock *pa_silence_memblock_new(pa_mempool *pool, const pa_sample_spec *spe } pa_memblock *pa_silence_memblock(pa_memblock* b, const pa_sample_spec *spec) { - void *data; - - assert(b); - assert(spec); - - data = pa_memblock_acquire(b); - pa_silence_memory(data, pa_memblock_get_length(b), spec); - pa_memblock_release(b); + assert(b && b->data && spec); + pa_silence_memory(b->data, b->length, spec); return b; } void pa_silence_memchunk(pa_memchunk *c, const pa_sample_spec *spec) { - void *data; - - assert(c); - assert(c->memblock); - assert(spec); + assert(c && c->memblock && c->memblock->data && spec && c->length); - data = pa_memblock_acquire(c->memblock); - pa_silence_memory((uint8_t*) data+c->index, c->length, spec); - pa_memblock_release(c->memblock); + pa_silence_memory((uint8_t*) c->memblock->data+c->index, c->length, spec); } void pa_silence_memory(void *p, size_t length, const pa_sample_spec *spec) { @@ -94,38 +82,26 @@ void pa_silence_memory(void *p, size_t length, const pa_sample_spec *spec) { } size_t pa_mix( - pa_mix_info streams[], - unsigned nstreams, - void *data, - size_t length, - const pa_sample_spec *spec, - const pa_cvolume *volume, - int mute) { - - pa_cvolume full_volume; - size_t d = 0; - unsigned k; + const pa_mix_info streams[], + unsigned nstreams, + void *data, + size_t length, + const pa_sample_spec *spec, + const pa_cvolume *volume, + int mute) { - assert(streams); - assert(data); - assert(length); - assert(spec); + assert(streams && data && length && spec); - if (!volume) - volume = pa_cvolume_reset(&full_volume, spec->channels); - - for (k = 0; k < nstreams; k++) - streams[k].internal = pa_memblock_acquire(streams[k].chunk.memblock); - switch (spec->format) { case PA_SAMPLE_S16NE:{ + size_t d; unsigned channel = 0; for (d = 0;; d += sizeof(int16_t)) { int32_t sum = 0; if (d >= length) - goto finish; + return d; if (!mute && volume->values[channel] != PA_VOLUME_MUTED) { unsigned i; @@ -135,12 +111,12 @@ size_t pa_mix( pa_volume_t cvolume = streams[i].volume.values[channel]; if (d >= streams[i].chunk.length) - goto finish; + return d; if (cvolume == PA_VOLUME_MUTED) v = 0; else { - v = *((int16_t*) ((uint8_t*) streams[i].internal + streams[i].chunk.index + d)); + v = *((int16_t*) ((uint8_t*) streams[i].chunk.memblock->data + streams[i].chunk.index + d)); if (cvolume != PA_VOLUME_NORM) v = (int32_t) (v * pa_sw_volume_to_linear(cvolume)); @@ -163,18 +139,17 @@ size_t pa_mix( if (++channel >= spec->channels) channel = 0; } - - break; } case PA_SAMPLE_S16RE:{ + size_t d; unsigned channel = 0; for (d = 0;; d += sizeof(int16_t)) { int32_t sum = 0; if (d >= length) - goto finish; + return d; if (!mute && volume->values[channel] != PA_VOLUME_MUTED) { unsigned i; @@ -184,12 +159,12 @@ size_t pa_mix( pa_volume_t cvolume = streams[i].volume.values[channel]; if (d >= streams[i].chunk.length) - goto finish; + return d; if (cvolume == PA_VOLUME_MUTED) v = 0; else { - v = INT16_SWAP(*((int16_t*) ((uint8_t*) streams[i].internal + streams[i].chunk.index + d))); + v = INT16_SWAP(*((int16_t*) ((uint8_t*) streams[i].chunk.memblock->data + streams[i].chunk.index + d))); if (cvolume != PA_VOLUME_NORM) v = (int32_t) (v * pa_sw_volume_to_linear(cvolume)); @@ -212,18 +187,17 @@ size_t pa_mix( if (++channel >= spec->channels) channel = 0; } - - break; } case PA_SAMPLE_U8: { + size_t d; unsigned channel = 0; for (d = 0;; d ++) { int32_t sum = 0; if (d >= length) - goto finish; + return d; if (!mute && volume->values[channel] != PA_VOLUME_MUTED) { unsigned i; @@ -233,12 +207,12 @@ size_t pa_mix( pa_volume_t cvolume = streams[i].volume.values[channel]; if (d >= streams[i].chunk.length) - goto finish; + return d; if (cvolume == PA_VOLUME_MUTED) v = 0; else { - v = (int32_t) *((uint8_t*) streams[i].internal + streams[i].chunk.index + d) - 0x80; + v = (int32_t) *((uint8_t*) streams[i].chunk.memblock->data + streams[i].chunk.index + d) - 0x80; if (cvolume != PA_VOLUME_NORM) v = (int32_t) (v * pa_sw_volume_to_linear(cvolume)); @@ -261,18 +235,17 @@ size_t pa_mix( if (++channel >= spec->channels) channel = 0; } - - break; } case PA_SAMPLE_FLOAT32NE: { + size_t d; unsigned channel = 0; for (d = 0;; d += sizeof(float)) { float sum = 0; if (d >= length) - goto finish; + return d; if (!mute && volume->values[channel] != PA_VOLUME_MUTED) { unsigned i; @@ -282,12 +255,12 @@ size_t pa_mix( pa_volume_t cvolume = streams[i].volume.values[channel]; if (d >= streams[i].chunk.length) - goto finish; + return d; if (cvolume == PA_VOLUME_MUTED) v = 0; else { - v = *((float*) ((uint8_t*) streams[i].internal + streams[i].chunk.index + d)); + v = *((float*) ((uint8_t*) streams[i].chunk.memblock->data + streams[i].chunk.index + d)); if (cvolume != PA_VOLUME_NORM) v *= pa_sw_volume_to_linear(cvolume); @@ -306,34 +279,17 @@ size_t pa_mix( if (++channel >= spec->channels) channel = 0; } - - break; } default: pa_log_error("ERROR: Unable to mix audio data of format %s.", pa_sample_format_to_string(spec->format)); abort(); } - -finish: - - for (k = 0; k < nstreams; k++) - pa_memblock_release(streams[k].chunk.memblock); - - return d; } -void pa_volume_memchunk( - pa_memchunk*c, - const pa_sample_spec *spec, - const pa_cvolume *volume) { - - void *ptr; - - assert(c); - assert(spec); - assert(c->length % pa_frame_size(spec) == 0); +void pa_volume_memchunk(pa_memchunk*c, const pa_sample_spec *spec, const pa_cvolume *volume) { + assert(c && spec && (c->length % pa_frame_size(spec) == 0)); assert(volume); if (pa_cvolume_channels_equal_to(volume, PA_VOLUME_NORM)) @@ -344,8 +300,6 @@ void pa_volume_memchunk( return; } - ptr = pa_memblock_acquire(c->memblock); - switch (spec->format) { case PA_SAMPLE_S16NE: { int16_t *d; @@ -356,7 +310,7 @@ void pa_volume_memchunk( for (channel = 0; channel < spec->channels; channel++) linear[channel] = pa_sw_volume_to_linear(volume->values[channel]); - for (channel = 0, d = (int16_t*) ((uint8_t*) ptr + c->index), n = c->length/sizeof(int16_t); n > 0; d++, n--) { + for (channel = 0, d = (int16_t*) ((uint8_t*) c->memblock->data+c->index), n = c->length/sizeof(int16_t); n > 0; d++, n--) { int32_t t = (int32_t)(*d); t = (int32_t) (t * linear[channel]); @@ -381,7 +335,7 @@ void pa_volume_memchunk( for (channel = 0; channel < spec->channels; channel++) linear[channel] = pa_sw_volume_to_linear(volume->values[channel]); - for (channel = 0, d = (int16_t*) ((uint8_t*) ptr + c->index), n = c->length/sizeof(int16_t); n > 0; d++, n--) { + for (channel = 0, d = (int16_t*) ((uint8_t*) c->memblock->data+c->index), n = c->length/sizeof(int16_t); n > 0; d++, n--) { int32_t t = (int32_t)(INT16_SWAP(*d)); t = (int32_t) (t * linear[channel]); @@ -403,7 +357,7 @@ void pa_volume_memchunk( size_t n; unsigned channel = 0; - for (d = (uint8_t*) ptr + c->index, n = c->length; n > 0; d++, n--) { + for (d = (uint8_t*) c->memblock->data + c->index, n = c->length; n > 0; d++, n--) { int32_t t = (int32_t) *d - 0x80; t = (int32_t) (t * pa_sw_volume_to_linear(volume->values[channel])); @@ -425,7 +379,7 @@ void pa_volume_memchunk( unsigned n; unsigned channel; - d = (float*) ((uint8_t*) ptr + c->index); + d = (float*) ((uint8_t*) c->memblock->data + c->index); skip = spec->channels * sizeof(float); n = c->length/sizeof(float)/spec->channels; @@ -448,7 +402,5 @@ void pa_volume_memchunk( pa_sample_format_to_string(spec->format)); abort(); } - - pa_memblock_release(c->memblock); } diff --git a/src/pulsecore/sample-util.h b/src/pulsecore/sample-util.h index 04c2f6b1..6b770792 100644 --- a/src/pulsecore/sample-util.h +++ b/src/pulsecore/sample-util.h @@ -36,11 +36,10 @@ typedef struct pa_mix_info { pa_memchunk chunk; pa_cvolume volume; void *userdata; - void *internal; /* Used internally by pa_mix(), should not be initialised when calling pa_mix() */ } pa_mix_info; size_t pa_mix( - pa_mix_info channels[], + const pa_mix_info channels[], unsigned nchannels, void *data, size_t length, diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index c3cd4952..d948f0a4 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -294,7 +294,6 @@ int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume) assert(i->state == PA_SINK_INPUT_RUNNING || i->state == PA_SINK_INPUT_DRAINED); if (i->move_silence > 0) { - size_t l; /* We have just been moved and shall play some silence for a * while until the old sink has drained its playback buffer */ @@ -304,8 +303,7 @@ int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume) chunk->memblock = pa_memblock_ref(i->silence_memblock); chunk->index = 0; - l = pa_memblock_get_length(chunk->memblock); - chunk->length = i->move_silence < l ? i->move_silence : l; + chunk->length = i->move_silence < chunk->memblock->length ? i->move_silence : chunk->memblock->length; ret = 0; do_volume_adj_here = 1; @@ -391,13 +389,10 @@ void pa_sink_input_drop(pa_sink_input *i, const pa_memchunk *chunk, size_t lengt if (i->move_silence > 0) { if (chunk) { - size_t l; - l = pa_memblock_get_length(i->silence_memblock); - if (chunk->memblock != i->silence_memblock || chunk->index != 0 || - (chunk->memblock && (chunk->length != (l < i->move_silence ? l : i->move_silence)))) + (chunk->memblock && (chunk->length != (i->silence_memblock->length < i->move_silence ? i->silence_memblock->length : i->move_silence)))) return; } diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 04795e39..05695254 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -237,6 +237,7 @@ static unsigned fill_mix_info(pa_sink *s, pa_mix_info *info, unsigned maxinfo) { info->userdata = i; assert(info->chunk.memblock); + assert(info->chunk.memblock->data); assert(info->chunk.length); info++; @@ -304,16 +305,13 @@ int pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) { pa_volume_memchunk(result, &s->sample_spec, &volume); } } else { - void *ptr; result->memblock = pa_memblock_new(s->core->mempool, length); assert(result->memblock); /* pa_log("mixing %i", n); */ - ptr = pa_memblock_acquire(result->memblock); - result->length = pa_mix(info, n, ptr, length, &s->sample_spec, &s->sw_volume, s->sw_muted); - pa_memblock_release(result->memblock); - + result->length = pa_mix(info, n, result->memblock->data, length, + &s->sample_spec, &s->sw_volume, s->sw_muted); result->index = 0; } @@ -334,13 +332,13 @@ int pa_sink_render_into(pa_sink*s, pa_memchunk *target) { pa_mix_info info[MAX_MIX_CHANNELS]; unsigned n; int r = -1; - void *ptr; assert(s); assert(s->ref >= 1); assert(target); assert(target->memblock); assert(target->length); + assert(target->memblock->data); pa_sink_ref(s); @@ -349,23 +347,16 @@ int pa_sink_render_into(pa_sink*s, pa_memchunk *target) { if (n <= 0) goto finish; - ptr = pa_memblock_acquire(target->memblock); - if (n == 1) { - void *src; pa_cvolume volume; if (target->length > info[0].chunk.length) target->length = info[0].chunk.length; - - src = pa_memblock_acquire(info[0].chunk.memblock); - memcpy((uint8_t*) ptr + target->index, - (uint8_t*) src + info[0].chunk.index, + memcpy((uint8_t*) target->memblock->data + target->index, + (uint8_t*) info[0].chunk.memblock->data + info[0].chunk.index, target->length); - pa_memblock_release(info[0].chunk.memblock); - pa_sw_cvolume_multiply(&volume, &s->sw_volume, &info[0].volume); if (s->sw_muted) @@ -374,13 +365,11 @@ int pa_sink_render_into(pa_sink*s, pa_memchunk *target) { pa_volume_memchunk(target, &s->sample_spec, &volume); } else target->length = pa_mix(info, n, - (uint8_t*) ptr + target->index, + (uint8_t*) target->memblock->data + target->index, target->length, &s->sample_spec, &s->sw_volume, s->sw_muted); - - pa_memblock_release(target->memblock); inputs_drop(s, info, n, target->length); @@ -404,6 +393,7 @@ void pa_sink_render_into_full(pa_sink *s, pa_memchunk *target) { assert(target); assert(target->memblock); assert(target->length); + assert(target->memblock->data); pa_sink_ref(s); diff --git a/src/pulsecore/sound-file-stream.c b/src/pulsecore/sound-file-stream.c index d2ffeeed..e6f24a79 100644 --- a/src/pulsecore/sound-file-stream.c +++ b/src/pulsecore/sound-file-stream.c @@ -74,26 +74,21 @@ static int sink_input_peek(pa_sink_input *i, pa_memchunk *chunk) { if (!u->memchunk.memblock) { uint32_t fs = pa_frame_size(&i->sample_spec); sf_count_t n; - void *p; u->memchunk.memblock = pa_memblock_new(i->sink->core->mempool, BUF_SIZE); u->memchunk.index = 0; - p = pa_memblock_acquire(u->memchunk.memblock); - if (u->readf_function) { - if ((n = u->readf_function(u->sndfile, p, BUF_SIZE/fs)) <= 0) + if ((n = u->readf_function(u->sndfile, u->memchunk.memblock->data, BUF_SIZE/fs)) <= 0) n = 0; u->memchunk.length = n * fs; } else { - if ((n = sf_read_raw(u->sndfile, p, BUF_SIZE)) <= 0) + if ((n = sf_read_raw(u->sndfile, u->memchunk.memblock->data, BUF_SIZE)) <= 0) n = 0; u->memchunk.length = n; } - - pa_memblock_release(u->memchunk.memblock); if (!u->memchunk.length) { free_userdata(u); diff --git a/src/pulsecore/sound-file.c b/src/pulsecore/sound-file.c index c74a1586..1bf650e2 100644 --- a/src/pulsecore/sound-file.c +++ b/src/pulsecore/sound-file.c @@ -40,11 +40,7 @@ int pa_sound_file_load(pa_mempool *pool, const char *fname, pa_sample_spec *ss, int ret = -1; size_t l; sf_count_t (*readf_function)(SNDFILE *sndfile, void *ptr, sf_count_t frames) = NULL; - void *ptr = NULL; - - assert(fname); - assert(ss); - assert(chunk); + assert(fname && ss && chunk); chunk->memblock = NULL; chunk->index = chunk->length = 0; @@ -101,10 +97,8 @@ int pa_sound_file_load(pa_mempool *pool, const char *fname, pa_sample_spec *ss, chunk->index = 0; chunk->length = l; - ptr = pa_memblock_acquire(chunk->memblock); - - if ((readf_function && readf_function(sf, ptr, sfinfo.frames) != sfinfo.frames) || - (!readf_function && sf_read_raw(sf, ptr, l) != l)) { + if ((readf_function && readf_function(sf, chunk->memblock->data, sfinfo.frames) != sfinfo.frames) || + (!readf_function && sf_read_raw(sf, chunk->memblock->data, l) != l)) { pa_log("Premature file end"); goto finish; } @@ -116,9 +110,6 @@ finish: if (sf) sf_close(sf); - if (ptr) - pa_memblock_release(chunk->memblock); - if (ret != 0 && chunk->memblock) pa_memblock_unref(chunk->memblock); diff --git a/src/tests/flist-test.c b/src/tests/flist-test.c index 06d68311..abc0659d 100644 --- a/src/tests/flist-test.c +++ b/src/tests/flist-test.c @@ -54,7 +54,7 @@ static void thread_func(void *data) { int b = 1; while (!quit) { - char *text; + char *text, *t; /* Allocate some memory, if possible take it from the flist */ if (b && (text = pa_flist_pop(flist))) diff --git a/src/tests/mcalign-test.c b/src/tests/mcalign-test.c index 1584256c..35691698 100644 --- a/src/tests/mcalign-test.c +++ b/src/tests/mcalign-test.c @@ -59,27 +59,24 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) { c.index = c.length = 0; } - assert(c.index < pa_memblock_get_length(c.memblock)); + assert(c.index < c.memblock->length); - l = pa_memblock_get_length(c.memblock) - c.index; + l = c.memblock->length - c.index; l = l <= 1 ? l : rand() % (l-1) +1 ; - - p = pa_memblock_acquire(c.memblock); - if ((r = read(STDIN_FILENO, (uint8_t*) p + c.index, l)) <= 0) { - pa_memblock_release(c.memblock); + + if ((r = read(STDIN_FILENO, (uint8_t*) c.memblock->data + c.index, l)) <= 0) { fprintf(stderr, "read() failed: %s\n", r < 0 ? strerror(errno) : "EOF"); break; } - pa_memblock_release(c.memblock); - + c.length = r; pa_mcalign_push(a, &c); fprintf(stderr, "Read %ld bytes\n", (long)r); c.index += r; - if (c.index >= pa_memblock_get_length(c.memblock)) { + if (c.index >= c.memblock->length) { pa_memblock_unref(c.memblock); pa_memchunk_reset(&c); } @@ -90,9 +87,7 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) { if (pa_mcalign_pop(a, &t) < 0) break; - p = pa_memblock_acquire(t.memblock); - pa_loop_write(STDOUT_FILENO, (uint8_t*) p + t.index, t.length, NULL); - pa_memblock_release(t.memblock); + pa_loop_write(STDOUT_FILENO, (uint8_t*) t.memblock->data + t.index, t.length, NULL); fprintf(stderr, "Wrote %lu bytes.\n", (unsigned long) t.length); pa_memblock_unref(t.memblock); diff --git a/src/tests/memblock-test.c b/src/tests/memblock-test.c index c2dd2efa..ef2e0ad7 100644 --- a/src/tests/memblock-test.c +++ b/src/tests/memblock-test.c @@ -76,7 +76,6 @@ int main(int argc, char *argv[]) { pa_memblock* blocks[5]; uint32_t id, shm_id; size_t offset, size; - char *x; const char txt[] = "This is a test!"; @@ -91,17 +90,10 @@ int main(int argc, char *argv[]) { assert(pool_a && pool_b && pool_c); blocks[0] = pa_memblock_new_fixed(pool_a, (void*) txt, sizeof(txt), 1); - blocks[1] = pa_memblock_new(pool_a, sizeof(txt)); - x = pa_memblock_acquire(blocks[1]); - snprintf(x, pa_memblock_get_length(blocks[1]), "%s", txt); - pa_memblock_release(blocks[1]); - + snprintf(blocks[1]->data, blocks[1]->length, "%s", txt); blocks[2] = pa_memblock_new_pool(pool_a, sizeof(txt)); - x = pa_memblock_acquire(blocks[2]); - snprintf(x, pa_memblock_get_length(blocks[2]), "%s", txt); - pa_memblock_release(blocks[1]); - + snprintf(blocks[2]->data, blocks[2]->length, "%s", txt); blocks[3] = pa_memblock_new_malloced(pool_a, pa_xstrdup(txt), sizeof(txt)); blocks[4] = NULL; @@ -138,18 +130,14 @@ int main(int argc, char *argv[]) { mb_c = pa_memimport_get(import_c, id, shm_id, offset, size); assert(mb_c); - x = pa_memblock_acquire(mb_c); - printf("1 data=%s\n", x); - pa_memblock_release(mb_c); + printf("1 data=%s\n", (char*) mb_c->data); print_stats(pool_a, "A"); print_stats(pool_b, "B"); print_stats(pool_c, "C"); pa_memexport_free(export_b); - x = pa_memblock_acquire(mb_c); - printf("2 data=%s\n", x); - pa_memblock_release(mb_c); + printf("2 data=%s\n", (char*) mb_c->data); pa_memblock_unref(mb_c); pa_memimport_free(import_b); diff --git a/src/tests/memblockq-test.c b/src/tests/memblockq-test.c index 02848eb2..1ac4577b 100644 --- a/src/tests/memblockq-test.c +++ b/src/tests/memblockq-test.c @@ -131,10 +131,8 @@ int main(int argc, char *argv[]) { if (pa_memblockq_peek(bq, &out) < 0) break; - p = pa_memblock_acquire(out.memblock); - for (e = (char*) p + out.index, n = 0; n < out.length; n++) + for (e = (char*) out.memblock->data + out.index, n = 0; n < out.length; n++) printf("%c", *e); - pa_memblock_release(out.memblock); pa_memblock_unref(out.memblock); pa_memblockq_drop(bq, &out, out.length); |