remote: use mmap helpers

Use the mmap helpers to only map the data that is needed.
This commit is contained in:
Wim Taymans 2017-12-01 12:42:18 +01:00
parent a8cbffac7f
commit 4019da39c1
2 changed files with 33 additions and 27 deletions

View file

@ -57,8 +57,7 @@ struct buffer_id {
uint32_t id; uint32_t id;
struct spa_buffer *buf; struct spa_buffer *buf;
void *ptr; void *ptr;
uint32_t offset; struct pw_map_range map;
uint32_t size;
}; };
struct port { struct port {
@ -870,7 +869,7 @@ static void clear_buffers(struct port *port)
pw_array_for_each(bid, &port->buffer_ids) { pw_array_for_each(bid, &port->buffer_ids) {
if (bid->ptr != NULL) { if (bid->ptr != NULL) {
if (munmap(bid->ptr, bid->size + bid->offset) < 0) if (munmap(bid->ptr, bid->map.size) < 0)
pw_log_warn("failed to unmap: %m"); pw_log_warn("failed to unmap: %m");
} }
bid->ptr = NULL; bid->ptr = NULL;
@ -926,7 +925,8 @@ client_node_port_use_buffers(void *object,
uint32_t i, j, len; uint32_t i, j, len;
struct spa_buffer *b, **bufs; struct spa_buffer *b, **bufs;
struct port *port; struct port *port;
struct pw_type *t = &proxy->remote->core->type; struct pw_core *core = proxy->remote->core;
struct pw_type *t = &core->type;
int res, prot; int res, prot;
port = find_port(data, direction, port_id); port = find_port(data, direction, port_id);
@ -956,17 +956,18 @@ client_node_port_use_buffers(void *object,
len = pw_array_get_len(&port->buffer_ids, struct buffer_id); len = pw_array_get_len(&port->buffer_ids, struct buffer_id);
bid = pw_array_add(&port->buffer_ids, sizeof(struct buffer_id)); bid = pw_array_add(&port->buffer_ids, sizeof(struct buffer_id));
bid->offset = buffers[i].offset; pw_map_range_init(&bid->map, buffers[i].offset, buffers[i].size, core->sc_pagesize);
bid->size = buffers[i].size;
bid->ptr = mmap(NULL, bid->offset + bid->size, prot, MAP_SHARED, mid->fd, 0); bid->ptr = mmap(NULL, bid->map.size, prot, MAP_SHARED, mid->fd, bid->map.offset);
if (bid->ptr == MAP_FAILED) { if (bid->ptr == MAP_FAILED) {
bid->ptr = NULL; bid->ptr = NULL;
pw_log_warn("Failed to mmap memory %u %p: %s", bid->size, mid, pw_log_warn("Failed to mmap memory %u %u: %m",
strerror(errno)); bid->map.offset, bid->map.size);
continue; continue;
} }
if (mlock(bid->ptr, bid->offset + bid->size) < 0) if (mlock(bid->ptr, bid->map.size) < 0)
pw_log_warn("Failed to lock memory %u %s", bid->offset + bid->size, strerror(errno)); pw_log_warn("Failed to mlock memory %u %u: %m",
bid->map.offset, bid->map.size);
b = buffers[i].buffer; b = buffers[i].buffer;
@ -992,9 +993,9 @@ client_node_port_use_buffers(void *object,
if (bid->id != len) { if (bid->id != len) {
pw_log_warn("unexpected id %u found, expected %u", bid->id, len); pw_log_warn("unexpected id %u found, expected %u", bid->id, len);
} }
pw_log_debug("add buffer %d %d %u %u", mid->id, bid->id, bid->offset, bid->size); pw_log_debug("add buffer %d %d %u %u", mid->id, bid->id, bid->map.offset, bid->map.size);
offset = bid->offset; offset = bid->map.start;
for (j = 0; j < b->n_metas; j++) { for (j = 0; j < b->n_metas; j++) {
struct spa_meta *m = &b->metas[j]; struct spa_meta *m = &b->metas[j];
memcpy(m, &buffers[i].buffer->metas[j], sizeof(struct spa_meta)); memcpy(m, &buffers[i].buffer->metas[j], sizeof(struct spa_meta));
@ -1017,7 +1018,8 @@ client_node_port_use_buffers(void *object,
d->fd = bmid->fd; d->fd = bmid->fd;
pw_log_debug(" data %d %u -> fd %d", j, bmid->id, bmid->fd); pw_log_debug(" data %d %u -> fd %d", j, bmid->id, bmid->fd);
} else if (d->type == t->data.MemPtr) { } else if (d->type == t->data.MemPtr) {
d->data = SPA_MEMBER(bid->ptr, bid->offset + SPA_PTR_TO_INT(d->data), void); d->data = SPA_MEMBER(bid->ptr,
bid->map.start + SPA_PTR_TO_INT(d->data), void);
d->fd = -1; d->fd = -1;
pw_log_debug(" data %d %u -> mem %p", j, bid->id, d->data); pw_log_debug(" data %d %u -> mem %p", j, bid->id, d->data);
} else { } else {
@ -1066,8 +1068,10 @@ client_node_port_set_io(void *object,
{ {
struct pw_proxy *proxy = object; struct pw_proxy *proxy = object;
struct node_data *data = proxy->user_data; struct node_data *data = proxy->user_data;
struct pw_core *core = proxy->remote->core;
struct port *port; struct port *port;
struct mem_id *mid; struct mem_id *mid;
struct pw_map_range r;
void *ptr; void *ptr;
port = find_port(data, direction, port_id); port = find_port(data, direction, port_id);
@ -1079,8 +1083,9 @@ client_node_port_set_io(void *object,
pw_log_warn("unknown memory id %u", memid); pw_log_warn("unknown memory id %u", memid);
return; return;
} }
pw_map_range_init(&r, offset, size, core->sc_pagesize);
ptr = mmap(NULL, offset + size, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_LOCKED, mid->fd, 0); ptr = mmap(NULL, r.size, PROT_READ|PROT_WRITE, MAP_SHARED, mid->fd, r.offset);
if (ptr == MAP_FAILED) { if (ptr == MAP_FAILED) {
pw_log_warn("Failed to mmap memory %d %p: %s", size, mid, pw_log_warn("Failed to mmap memory %d %p: %s", size, mid,
strerror(errno)); strerror(errno));
@ -1090,7 +1095,7 @@ client_node_port_set_io(void *object,
spa_node_port_set_io(port->port->node->node, spa_node_port_set_io(port->port->node->node,
direction, port_id, direction, port_id,
id, id,
SPA_MEMBER(ptr, offset, void), SPA_MEMBER(ptr, r.start, void),
size); size);
} }

View file

@ -54,8 +54,7 @@ struct buffer_id {
bool used; bool used;
struct spa_buffer *buf; struct spa_buffer *buf;
void *ptr; void *ptr;
uint32_t offset; struct pw_map_range map;
uint32_t size;
}; };
struct stream { struct stream {
@ -146,7 +145,7 @@ static void clear_buffers(struct pw_stream *stream)
pw_array_for_each(bid, &impl->buffer_ids) { pw_array_for_each(bid, &impl->buffer_ids) {
spa_hook_list_call(&stream->listener_list, struct pw_stream_events, remove_buffer, bid->id); spa_hook_list_call(&stream->listener_list, struct pw_stream_events, remove_buffer, bid->id);
if (bid->ptr != NULL) if (bid->ptr != NULL)
if (munmap(bid->ptr, bid->size + bid->offset) < 0) if (munmap(bid->ptr, bid->map.size) < 0)
pw_log_warn("failed to unmap buffer: %m"); pw_log_warn("failed to unmap buffer: %m");
bid->ptr = NULL; bid->ptr = NULL;
free(bid->buf); free(bid->buf);
@ -826,7 +825,8 @@ client_node_port_use_buffers(void *data,
{ {
struct stream *impl = data; struct stream *impl = data;
struct pw_stream *stream = &impl->this; struct pw_stream *stream = &impl->this;
struct pw_type *t = &stream->remote->core->type; struct pw_core *core = stream->remote->core;
struct pw_type *t = &core->type;
struct buffer_id *bid; struct buffer_id *bid;
uint32_t i, j, len; uint32_t i, j, len;
struct spa_buffer *b; struct spa_buffer *b;
@ -857,13 +857,12 @@ client_node_port_use_buffers(void *data,
b = buffers[i].buffer; b = buffers[i].buffer;
bid->offset = buffers[i].offset; pw_map_range_init(&bid->map, buffers[i].offset, buffers[i].size, core->sc_pagesize);
bid->size = buffers[i].size;
bid->ptr = mmap(NULL, bid->offset + bid->size, prot, MAP_SHARED, mid->fd, 0); bid->ptr = mmap(NULL, bid->map.size, prot, MAP_SHARED, mid->fd, bid->map.offset);
if (bid->ptr == MAP_FAILED) { if (bid->ptr == MAP_FAILED) {
bid->ptr = NULL; bid->ptr = NULL;
pw_log_warn("Failed to mmap memory %d %p: %s", bid->size, mid, pw_log_warn("Failed to mmap memory %d %p: %s", bid->map.size, mid,
strerror(errno)); strerror(errno));
continue; continue;
} }
@ -891,9 +890,10 @@ client_node_port_use_buffers(void *data,
pw_log_warn("unexpected id %u found, expected %u", bid->id, len); pw_log_warn("unexpected id %u found, expected %u", bid->id, len);
impl->in_order = false; impl->in_order = false;
} }
pw_log_debug("add buffer %d %d %u %u", mid->id, bid->id, bid->offset, bid->size); pw_log_debug("add buffer %d %d %u %u", mid->id,
bid->id, bid->map.offset, bid->map.size);
offset = bid->offset; offset = bid->map.start;
for (j = 0; j < b->n_metas; j++) { for (j = 0; j < b->n_metas; j++) {
struct spa_meta *m = &b->metas[j]; struct spa_meta *m = &b->metas[j];
memcpy(m, &buffers[i].buffer->metas[j], sizeof(struct spa_meta)); memcpy(m, &buffers[i].buffer->metas[j], sizeof(struct spa_meta));
@ -915,7 +915,8 @@ client_node_port_use_buffers(void *data,
d->fd = bmid->fd; d->fd = bmid->fd;
pw_log_debug(" data %d %u -> fd %d", j, bmid->id, bmid->fd); pw_log_debug(" data %d %u -> fd %d", j, bmid->id, bmid->fd);
} else if (d->type == t->data.MemPtr) { } else if (d->type == t->data.MemPtr) {
d->data = SPA_MEMBER(bid->ptr, bid->offset + SPA_PTR_TO_INT(d->data), void); d->data = SPA_MEMBER(bid->ptr,
bid->map.start + SPA_PTR_TO_INT(d->data), void);
d->fd = -1; d->fd = -1;
pw_log_debug(" data %d %u -> mem %p", j, bid->id, d->data); pw_log_debug(" data %d %u -> mem %p", j, bid->id, d->data);
} else { } else {