Huh? The physical memory manager handles allocating and freeing physical pages. It has nothing to do with allocating linear address space. In my design, physical memory for a linear adress is almost always allocated by the pagefault handler. The only exception is some device-drivers using DMA.JamesM wrote:This is what a physical memory manager is for. Dear me, you really have difficulty with the concept of encapsulation, don't you?It is still different from page-aligned, which could be implemented without any type of memory-control blocks.
common dynamic memory allocator API
Re: common dynamic memory allocator API
- gravaera
- Member
- Posts: 737
- Joined: Tue Jun 02, 2009 4:35 pm
- Location: Supporting the cause: Use \tabs to indent code. NOT \x20 spaces.
Re: common dynamic memory allocator API
@rdos: Please stop going on and on about your gangsta "assembly only" OS: it's off topic. If you think that this proposal doesn't suit your kernel, then don't use it.
17:56 < sortie> Paging is called paging because you need to draw it on pages in your notebook to succeed at it.
Re: common dynamic memory allocator API
No, you're quite right. I certainly haven't got to the stage of jumping to user mode.rdos wrote:Really? I suppose you haven't yet come to the stage where you run applications on user-level ring.JamesM wrote:Quite. In general the heap serving an OS kernel should not need to worry about permissions, as the memory it serves will always be accessed in supervisor mode.
Douche.
FYI, memory allocated by user applications running on a non-kernel ring will not use the kernel heap allocator, will they?. Honestly, if you are going to ruin every single intellectual discussion on this forum with the limitations and failure to properly encapsulate functionality in your own OS, please engage brain before replying.FYI, memory allocated by user applications running on non-kernel ring, will need OS support for allocating memory, and you just cannot hand it memory allocated for supervisor mode. Well, you can, but it would be a lousy system.
On-demand page allocation makes a lot of sense, but not in this area. If I call "malloc(32)", the likelihood is that I'm going to use those 32 bytes very shortly, if not immediately. For no other reason, maybe, than to memset(ptr, 0, 32). If I've specifically requested some heap memory, why try and second-guess me and assume I'm not going to access it soon? You're wasting time with that page fault.That's not how I allocate kernel memory.JamesM wrote:"Get a page" from the physical memory allocator, map it using the virtual memory manager, carve it up in some heap-algorithm-specific way, track it, return parts of it, dispose of it back to the physical memory manager at some point when it is free again.
Now, if we were talking about some other memory subsystem, like a file being memory-mapped or a large memory-mapped area; yes, I agree with you.
But we're not, so I don't.
I use the word "heap" because it is called a heap.I see no reason to use the word "heap".JamesM wrote:Oh, and a "heap" is a dynamically-sized store of data with global scope. Even for assembly, you use the stack for local data (or promote directly to registers) -data with scope longer than the current routine invocation must be either placed statically in global memory or allocated on <some kind of> heap. Whether you call it that or not.
I could call it a "camel", instead. But I wouldn't, because it's a heap.
Re: common dynamic memory allocator API
In an attempt to get this back on track...
Unless I am mistaken, what Nick suggested is an API "standard" for memory-related system calls to be called from user space.
The idea would be that your user-space implementation of malloc(), free(), realloc() etc. etc. doesn't have to bother with whether your kernel uses something like sbrk() or mmap() or whatever to actually provide that memory. (Perhaps you could use this abstraction layer even for kernel-space work.) Right?
As such, I certainly see benefits there. If anything, it would make the implementation of that particular corner of my PDCLib real easy. I don't really look forward to adapting my C library to a multitude of memory-handling system calls that are out there.
Please tell me if I'm on the right track here or whether I have misunderstood the whole thing, before I try to contribute "in the wrong direction".
@ rdos:
You have code, data, stack, and heap. That's standard nomenclature in software engineering. You can call it whatever you like, but you'll have to deal with the fact that those names are used by virtually everybody else, and will have problems with whatever custom nomenclature you might have come up with.
Unless I am mistaken, what Nick suggested is an API "standard" for memory-related system calls to be called from user space.
The idea would be that your user-space implementation of malloc(), free(), realloc() etc. etc. doesn't have to bother with whether your kernel uses something like sbrk() or mmap() or whatever to actually provide that memory. (Perhaps you could use this abstraction layer even for kernel-space work.) Right?
As such, I certainly see benefits there. If anything, it would make the implementation of that particular corner of my PDCLib real easy. I don't really look forward to adapting my C library to a multitude of memory-handling system calls that are out there.
Please tell me if I'm on the right track here or whether I have misunderstood the whole thing, before I try to contribute "in the wrong direction".
@ rdos:
You have code, data, stack, and heap. That's standard nomenclature in software engineering. You can call it whatever you like, but you'll have to deal with the fact that those names are used by virtually everybody else, and will have problems with whatever custom nomenclature you might have come up with.
Every good solution is obvious once you've found it.
Re: common dynamic memory allocator API
I took Nick's suggestion (even though he hinted at use for userspace also) as mainly for the kernel memory allocator. The sheer number of heap allocations and deallocations means that a syscall for each would be extremely wasteful, which is why the mmap/sbrk interface between userspace and kernelspace is used in the first place.Solar wrote:In an attempt to get this back on track...
Unless I am mistaken, what Nick suggested is an API "standard" for memory-related system calls to be called from user space.
The idea would be that your user-space implementation of malloc(), free(), realloc() etc. etc. doesn't have to bother with whether your kernel uses something like sbrk() or mmap() or whatever to actually provide that memory. (Perhaps you could use this abstraction layer even for kernel-space work.) Right?
As such, I certainly see benefits there. If anything, it would make the implementation of that particular corner of my PDCLib real easy. I don't really look forward to adapting my C library to a multitude of memory-handling system calls that are out there.
Please tell me if I'm on the right track here or whether I have misunderstood the whole thing, before I try to contribute "in the wrong direction".
@ rdos:
You have code, data, stack, and heap. That's standard nomenclature in software engineering. You can call it whatever you like, but you'll have to deal with the fact that those names are used by virtually everybody else, and will have problems with whatever custom nomenclature you might have come up with.
Re: common dynamic memory allocator API
Of course a user-space malloc() would usually allocate a larger chunk of memory at once, and parcel it out to the application, instead of making a system call for every allocation.JamesM wrote:The sheer number of heap allocations and deallocations means that a syscall for each would be extremely wasteful, which is why the mmap/sbrk interface between userspace and kernelspace is used in the first place.
But mmap / sbrk are not exactly "standard" (unless you're only looking at the POSIX world), and not very elegant either. Especially sbrk() is severely leaking abstraction, and mmap() isn't what I would call a "slim" interface either.
Consider: If you're using sbrk(), you cannot return memory to the system unless the topmost "chunk" of memory has been completely deallocated by the application - even if one or more "chunks" below that have been deallocated already (because sbrk() is strictly linear).
And you can't easily switch between sbrk() and mmap() as the memory-providing syscalls either. Nick's suggested API would make things much easier on the system malloc().
I am already considering Nick's API suggestions as the abstraction level for the PDCLib malloc(). That's why I joined this thread.
Last edited by Solar on Wed Nov 03, 2010 9:02 am, edited 1 time in total.
Every good solution is obvious once you've found it.
Re: common dynamic memory allocator API
Absolutely, but unless you extend the scope of this drastically you're not going to be able to define a replacement. My impression of Nick's suggestion was just the generic heap allocation/tracking algorithm with the thinnest possible wrapper to the outside world.Solar wrote:Of course a user-space malloc() would usually allocate a larger chunk of memory at once, and parcel it out to the application, instead of making a system call for every allocation.JamesM wrote:The sheer number of heap allocations and deallocations means that a syscall for each would be extremely wasteful, which is why the mmap/sbrk interface between userspace and kernelspace is used in the first place.
But mmap / sbrk are not exactly "standard" (unless you're only looking at the POSIX world), and not very elegant either. Especially sbrk() is severely leaking abstraction, and mmap() isn't what I would call a "slim" interface either.
Consider: If you're using sbrk(), you cannot return memory to the system unless the topmost "chunk" of memory has been completely deallocated by the application - even if the "chunks" below that have been deallocated already. And you can't easily switch between sbrk() and mmap() as the memory-providing syscalls either. Nick's suggested API would make things much easier on the system malloc()...
Re: common dynamic memory allocator API
Anyone wanting to use my C library and not being able to serve my abstraction layer is welcome to maintain his own set of patches to make PDCLib work with his OS API.JamesM wrote:Absolutely, but unless you extend the scope of this drastically you're not going to be able to define a replacement.
The "abstraction layer" I am using for my makeshift malloc() is ridiculous (thinly disguised sbrk()), and cannot return memory to the system at all. And I am not going for sbrk() / mmap() as the "abstraction layer" either. That's why I am interested in Nick's concept (if I understood it correctly, as I said).
Nick?
Every good solution is obvious once you've found it.
Re: common dynamic memory allocator API
I think if you understood it correctly, then I understood it incorrectly, and vice versa!Solar wrote:Anyone wanting to use my C library and not being able to serve my abstraction layer is welcome to maintain his own set of patches to make PDCLib work with his OS API.JamesM wrote:Absolutely, but unless you extend the scope of this drastically you're not going to be able to define a replacement.
The "abstraction layer" I am using for my makeshift malloc() is ridiculous (thinly disguised sbrk()), and cannot return memory to the system at all. And I am not going for sbrk() / mmap() as the "abstraction layer" either. That's why I am interested in Nick's concept (if I understood it correctly, as I said).
Nick?
Nick?
Re: common dynamic memory allocator API
I'm not sure about why this would matter. If we consider a paged OS where each user program runs in its own address space, it won't matter if you can return memory or not. You are basically allocating linear memory in the application's private address space, so there is no need for returning anything. Actually, I personally see no use in sbrk() either, as the entire private linear address space is already committed to the application.Solar wrote:Consider: If you're using sbrk(), you cannot return memory to the system unless the topmost "chunk" of memory has been completely deallocated by the application - even if one or more "chunks" below that have been deallocated already (because sbrk() is strictly linear).
Re: common dynamic memory allocator API
Returning memory (by lowering the brk pointer or using munmap) tells the memory manager explicitly that the associated physical memory is no longer needed by the application.rdos wrote:I'm not sure about why this would matter. If we consider a paged OS where each user program runs in its own address space, it won't matter if you can return memory or not. You are basically allocating linear memory in the application's private address space, so there is no need for returning anything. Actually, I personally see no use in sbrk() either, as the entire private linear address space is already committed to the application.Solar wrote:Consider: If you're using sbrk(), you cannot return memory to the system unless the topmost "chunk" of memory has been completely deallocated by the application - even if one or more "chunks" below that have been deallocated already (because sbrk() is strictly linear).
If a trainstation is where trains stop, what is a workstation ?
- NickJohnson
- Member
- Posts: 1249
- Joined: Tue Mar 24, 2009 8:11 pm
- Location: Sunnyvale, California
Re: common dynamic memory allocator API
@JamesM/Solar: You're sort of both right. One point is to have an abstraction layer (not standardized system calls, just a wrapper) over native OS memory management functions, so that allocators could be written portably. The other is to have a standard interface for written allocators, so any allocator written for the API can be used with any library/kernel/whatever implementing the API. So it's really two APIs: one for building allocators, and one for allocators to implement.
The set of functions I originally posted was for the allocators to implement. Those three functions seem to encompass all needed functionality. The things I'm not sure of are the best way to make allocators provide those frontend functions to the system (just normal functions? function pointers in structures?), and the best way to make a wrapper over various OS memory management functions.
The idea is to have these allocators available for not only kernels but also C libraries (I happen to be writing my own, and PDCLib seems to have a pretty stubbed-out malloc.) And possibly even applications that need special allocators for speed (things like Firefox seem to have internal APIs like this to handle different allocator options.) Of course, the last one falls outside the realm of osdev...
So, to try and get this discussion back on track:
What low level memory management functions are common enough to need to accommodate with this wrapper? (mmap/munmap (for kernels and some userspaces) and brk (simpler *nix systems) at least, but flat, unpaged systems should be considered too.) What should constitute the wrapper?
The set of functions I originally posted was for the allocators to implement. Those three functions seem to encompass all needed functionality. The things I'm not sure of are the best way to make allocators provide those frontend functions to the system (just normal functions? function pointers in structures?), and the best way to make a wrapper over various OS memory management functions.
The idea is to have these allocators available for not only kernels but also C libraries (I happen to be writing my own, and PDCLib seems to have a pretty stubbed-out malloc.) And possibly even applications that need special allocators for speed (things like Firefox seem to have internal APIs like this to handle different allocator options.) Of course, the last one falls outside the realm of osdev...
So, to try and get this discussion back on track:
What low level memory management functions are common enough to need to accommodate with this wrapper? (mmap/munmap (for kernels and some userspaces) and brk (simpler *nix systems) at least, but flat, unpaged systems should be considered too.) What should constitute the wrapper?
Re: common dynamic memory allocator API
Yes, but as have already been discussed, few, if any, allocators that grabs a piece of memory will ever be able to return some of it back to the OS, so linear address space that have been comitted for physical storage never free the physical storage. Instead, typical loaders free the whole address-space once the application terminates. The exception is segmented designs, where the selector base can be changed, and thus the heap can be compacted and partly released.gerryg400 wrote:Returning memory (by lowering the brk pointer or using munmap) tells the memory manager explicitly that the associated physical memory is no longer needed by the application.rdos wrote:I'm not sure about why this would matter. If we consider a paged OS where each user program runs in its own address space, it won't matter if you can return memory or not. You are basically allocating linear memory in the application's private address space, so there is no need for returning anything. Actually, I personally see no use in sbrk() either, as the entire private linear address space is already committed to the application.
To solve this problem (for larger allocations), it is much better to allocate directly from the page-tables (page-aligned), and then the physical pages can be freed once the allocation is freed. This is possible because there is no other allocation affected when the pages are freed. It can be done for "memory subdividers" as well, but the algorithm is more complex. The allocator needs to find entire pages that are free, and then free their physical storage.
Re: common dynamic memory allocator API
To cut this short, I would consider any such allocator to be broken by design and unfit for use in any "serious" OS.rdos wrote:...few, if any, allocators that grabs a piece of memory will ever be able to return some of it back to the OS...
Every good solution is obvious once you've found it.
Re: common dynamic memory allocator API
Rdos, what on earth are you talking about ?
BTW, my post was in response to a statement you made saying
That's not true. Many allocators including the malloc() that I use (from newlib) can munmap memory during free() if the O/S supports it. Most do.few, if any, allocators that grabs a piece of memory will ever be able to return some of it back to the OS, so linear address space that have been comitted for physical storage never free the physical storage.
BTW, my post was in response to a statement you made saying
So you start by saying that it doesn't matter whether or not memory is returned memory to the system and conclude with 'a much better way' to return memory to the system.I'm not sure about why this would matter. If we consider a paged OS where each user program runs in its own address space, it won't matter if you can return memory or not. You are basically allocating linear memory in the application's private address space, so there is no need for returning anything.
If a trainstation is where trains stop, what is a workstation ?