diff options
author | Miles Bader <miles@gnu.org> | 1996-01-23 21:35:50 +0000 |
---|---|---|
committer | Miles Bader <miles@gnu.org> | 1996-01-23 21:35:50 +0000 |
commit | 4ea74a6574580652ebf2e69221ba4333d9ebd413 (patch) | |
tree | 4c2674fa890b86cfc4fca399f9bf18bea1b81e22 | |
parent | f868ff815c35b263374a887b122343f6e95daee3 (diff) |
(packet_read): If there's lots of empty space at the beginning of a
vm_alloced buffer, deallocate it.
-rw-r--r-- | libpipe/pq.c | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/libpipe/pq.c b/libpipe/pq.c index 25bc38cb..ad31c8cd 100644 --- a/libpipe/pq.c +++ b/libpipe/pq.c @@ -354,11 +354,11 @@ packet_read (struct packet *packet, if (amount > 0) { + char *buf = packet->buf; + if (packet->buf_vm_alloced && amount >= vm_page_size) /* We can return memory from BUF directly without copying. */ { - char *buf = packet->buf; - if (buf + vm_page_size <= start) /* BUF_START has been advanced past the start of the buffer (perhaps by a series of small reads); as we're going to assume @@ -399,8 +399,27 @@ packet_read (struct packet *packet, { if (*data_len < amount) vm_allocate (mach_task_self (), (vm_address_t *)data, amount, 1); + bcopy (start, *data, amount); - packet->buf_start = start + amount; + start += amount; + + if (start - buf > 2 * PACKET_SIZE_LARGE) + /* Get rid of unused space at the beginning of the buffer -- we + know it's vm_alloced because of the size, and this will allow + the buffer to just slide through memory. Because we wait for + a relatively large amount of free space before doing this, and + packet_write() would have gotten rid the free space if it + didn't require copying much data, it's unlikely that this will + happen if it would have been cheaper to just move the packet + contents around to make space for the next write. */ + { + vm_size_t dealloc = trunc_page (start) - (vm_address_t)buf; + vm_deallocate (mach_task_self (), (vm_address_t)buf, dealloc); + packet->buf = buf + dealloc; + packet->buf_len -= dealloc; + } + + packet->buf_start = start; } } *data_len = amount; |