In C I have a function foo(char *) that accepts a memory pointer.
In the caller, I have two different memory buffers,
which I need to concatenate so I can pass one pointer foo().
Is there a way for me to do that without actually copying one buffer
to the end of the other buffer and without changing foo() itself?
I.e make the two buffers appear as one virtual continuous buffer to foo()
I need this for performance reasons. An O(n) solution (where n is one of the buffers length) is not acceptable for my case.
Also, a Linux specific solution is fine, if it helps.
This question seems to ask whether it is possible to concatenate the contents of two buffers (A and B) with the following constraints:
Given all that, my answer is no: it is not possible.
Yes, an OS kernel can use the CPU's MMU (memory management unit, on architectures that have one) to remap memory in either the kernel virtual address space or the user virtual address space. Allocate a contiguous chunk of virtual address space, then remap A and B into that buffer by modifying the page table entries for the chunk of virtual address space to point to the physical addresses of A and B.
This doesn't change the virtual address of A per se (since the old virtual address is still valid), but it does require you to access it through a different virtual address. This may be a problem.
The granularity of this remapping on today's typical CPU architectures is based on the page size(s), and since A and B are not page aligned nor are they a multiple of the page size, you will not be able to make them completely line up. This is definitely a problem.
Remapping N bytes requires modifying at least one page table entry for every M bytes, where M is the page size. This means that the remapping operation has a computational complexity of O(n) anyway. Other operations such as allocating more physical pages for page tables, flushing caches and TLBs, etc. would have additional performance implications.
Also, I'm wondering if the goal of this question somehow involves DMA (direct memory access). When performing DMA with an archaic device that requires contiguous memory, no amount of remapping is going to help unless you have an IOMMU at your disposal. And a modern device that can do scatter-gather DMA wouldn't require contiguous buffers in the first place.
Yes, there is a way.
Allocate memory for the buffers in a such way that they are adjacent in memory.
Example:
char* a = malloc(a_size + b_size);
char* b = a + a_size;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With