0

Does mmap (when called with MAP_ANONYMOUS, that is, for allocating memory) always return higher memory address than a previous call? If not so, Is there any way to make it return a higher address always?

MetallicPriest
  • 29,191
  • 52
  • 200
  • 356
  • 4
    Why would you need it to do this? – Oliver Charlesworth Dec 14 '11 at 12:14
  • Well, in my application, I am keeping starting addresses of all memories allocated through mmap in an array and I need to search them at some points. Having them in an sorted form will allow me to perform binary search. You can say, I can sort them after each time I call mmap, but the trouble is that this array needs to be read from inside a signal hander, and you know you cannot use mutexes or semaphores inside a signal handler, which becomes a problem if some thread is sorting the array while it is being read from inside a signal handler. – MetallicPriest Dec 14 '11 at 12:19
  • Insert the mapping's address at the correct position when creating the mapping then? Assuming you don't create a billion mappings every second, this is basically zero cost and your array is sorted. If you can't afford one additional `memmove` per `mmap`, something is wrong. – Damon Dec 14 '11 at 12:24
  • @MetallicPriest As I told you elsewhere (in another reply to another question), you could try using mutexes inside a SIGSEGV handler, and I believe it would often practically work on today's Linux systems, even if it is not guaranteed and not Posix conforming. – Basile Starynkevitch Dec 14 '11 at 12:25
  • 1
    Two comments: (1) When adding a new entry, you could sort *a copy* of the array and then flip the pointer. (2) How important is sorting anyway? A linear search might be feasible if the number of `mmap`ed regions is fairly small. – NPE Dec 14 '11 at 12:29
  • @aix: "When adding a new entry, you could sort a copy of the array and then flip the pointer." This is what I was thinking too! But the problem here is if several different threads are calling mmap at the same time! – MetallicPriest Dec 14 '11 at 12:33
  • You could: (1) make a copy of the array; (2) add the new entry; (3) sort; (4) try to compare-and-swap the new pointer into place, **returning to step 1 if this fails**. – NPE Dec 14 '11 at 12:36
  • I don't think that several threads can call `mmap` at exactly the same time. Since `mmap` modifies the memory space, it is probably impacting all the threads at the same time, so is probably serialized by the kernel (I imagine the kernel has a lock on the memory space descriptor). – Basile Starynkevitch Dec 14 '11 at 12:37

2 Answers2

3

By default, mmap can return any address aligned on a page boundary, in any order.

If you want to enforce that the returned address is the one you specify, you can use the MAP_FIXED flag, but that isn't very portable and reliable. This way you are tying your code with the particular implementation of mmap on a particular kernel.

But anyway, why would you always need a higher address than the previous one? Possibly a better way is to change the logic of your program.

Blagovest Buyukliev
  • 42,498
  • 14
  • 94
  • 130
3

Not necessarily, at least not according to its definition.

And I would believe that with ASLR it could happen that upper addresses are no more available, so mmap has to choose some lower address range.

Obviously, on 32 bits processors (& kernels) the memory space could be nearly filled, so when asking for a big mmap-ed range the kernel should find one which fits, and that could be anywhere.

If you want a monotone direction, use sbrk (but I really recommend against using it).

Another possibility could be to pre-allocate a very large amount (e.g. several terabytes) of address space using mmap with MAP_NORESERVE at program initialization, and call mmap with MAP_FIXED inside that range again to get the really usable space (in more manageable chunks, e.g. dozens of megabytes).

@MetallicPriest: you really should motivate and explain much more your questions. There are so mysterious and weird (and even I cannot guess all the context) that it is not very fun to answer them.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • That looks like a good solution. What I understand from MAP_NORESERVE is that the kernel won't allocate physical memory when mmap is called, but only when you call it again with MAP_FIXED. So the first call to mmap with MAP_NORESERVE will actually reserve the memory addresses without demand physical memory, and therefore calling MAP_FIXED in that range would be safe, right? – MetallicPriest Dec 14 '11 at 12:47
  • Yes. The disadvantage of `MAP_NORESERVE` is that the address range is reserved (so plain `mmap` with `MAP_ANONYMOUS` won't get it), but not the address space (on swap). You can perhaps get `SIGSEGV` when accessing `MAP_NORESERVE`-d space. – Basile Starynkevitch Dec 14 '11 at 12:54