Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!samsung!munnari.oz.au!yoyo.aarnet.edu.au!sirius.ucs.adelaide.edu.au!hydra!francis From: francis@cs.ua.oz.au (Francis Vaughan) Newsgroups: comp.os.mach Subject: Re: Efficient copying from task to task Message-ID: <3319@sirius.ucs.adelaide.edu.au> Date: 19 May 91 13:44:18 GMT References: <1991May17.074526.19128@sics.se> Sender: news@ucs.adelaide.edu.au Reply-To: francis@cs.adelaide.edu.au Distribution: comp Organization: Adelaide Univerity, Computer Science Lines: 117 Nntp-Posting-Host: hydra.ua.oz.au In article <1991May17.074526.19128@sics.se>, roland@sics.se (Roland Karlsson) writes: |> |> I have two tasks with the same virtual memory layout. Now I want to |> (very efficiently) copy a block from one task to another task. The |> block shall be at the same addresses in both tasks. The block do not |> have to start or end at page boundaries. The block can consist of any |> number of integers. It can be just some bytes or several megabytes. |> This copying is made very frequently during execution of several one |> thread tasks (=processes). UH? What do you mean by "thread tasks (=processes)" Do you really mean that you must have two seperate virtual address spaces (= task = process) or can you actually do it with multiple threads within the one task? What do you use for sychronisation at the moment? I would first of all think very hard about building you problem as a multiply threaded task. If you cannot, you have a problem since all virtual memory is handled on page boundaries. Unless you have some pressing problem however this should not be too bad. Just keep your other data out of the page. |> Proposal one: |> ------------ |> The solution in UNIX was to map the memory, to a file, with mmap. All |> UNIX processes can then map other processes memory to another address. |> Then can an ordinary block copy be used. |> |> I have tried to use vm_map to implement this behavior, but in without |> success. Every time I use vm_map (with the memory_object |> MEMORY_OBJECT_NULL) to the same offset in the memory object it looks |> like I get a new piece of memory, not an alias for the same. Can it |> be done??? Someone said the magical word "external pager" but I do |> not know how to use it. vm_map is not the correct call. You need map_fd(); This will get you a pretty good aproximation to what you are used to. (I think.) To use vm_map you would need to provide you own external pager. However fd_map does what you need with the inode pager (which is actually an external pager). You only need an external pager if you want something really fancy in the way of virtual memory behavior. Be aware of a bug in Mach. fd_map() is a read-only map. Alterations in the memory object are not reflected in the file. The only way to get the alterations back is to write(); them. If you write the page back to the mapped file with write() and the page is not resident in physical memory the kernel will crash. (A conflict in locks to the inode I belive.) You need to touch the page first to be sure. If anyone really needs to write an external pager I have a usefull litle example external pager that makes a good stub for writing real ones. |> Proposal two: |> ------------ |> You could ignore the above mapping method and use a combination of |> vm_write (for integral pages) and copying via a buffer (for parts of |> pages). This should be straight forward I think. But I do not want |> to copy via a buffer (this means copying two times) and I would also |> like to use vm_read (this means also copying two times) as the task |> that wants the memory otherwise would be idle during copying (when |> they could copy half the memory each). Just use IPC, at least you only need to do the copy once then. But still maybe sub-optimal. The kernel copes with messing about with copying and remapping stuff for IPC tranfsers. However it won't put out of line data where you want. (Which is a pity.) So you need to copy it from the IPC buffer. Have a look at MIG too. Neat and relativly easy to use once you are used to it. |> Refinement one to proposal two: |> ------------------------------- |> It would be very nice if I could use a "copy on write" technique to |> copy the integral pages from one task to another task. How can that |> be made??? Do you really mean copy-on-write? You previous description conflicts with this. (sort of.) To do what I think you mean just set the memory you want to share as VM_INHERIT_SHARE (or VM-INHERIT-COPY) with the vm_inherit() call (page aligned memory again) and fork() the shareing tasks. However copy-on-write means you get a copy the first time you write and then thats it. I dont think thats what you meant. SHARE means that it really is shared with no sychronisation. You need to build you own. |> Refinement two to proposal two: |> ------------------------------- |> Can I write/read parts of pages to/from another tasks memory without |> mapping??? Then I do not have to copy twice for small blocks. Again maybe use IPC. |> Proposal three: |> -------------- |> Something completely different. But what??? Mutli-thread the problem. Use cthreads and its locking primitives. If you are building data in place and then making it available once it is ready, you will never get away without copying it at least once. When it comes down to it, most of the above are just different variants on using IPC do shuffle memory around. There is not quite enough information about you problem to really give definitive advice. Hope these ramblings are of some use. Francis Vaughan.