Hi Stefan, On 12/31/2010 5:04 AM, Stefan Reuther wrote: [attributions elided]>>>> So, I need a "currency" that tasks can use to balance their "wants" with >>>> their "abilities". So, the information concerning the relative values >>>> of those resources can remain encapsulated in the task and not exported >>>> to some other "mechanism" for enforcement "from without". >>> >>> How many tasks do you think will be capable of such resource exchange ? >> >> It's an inherent part of the API. IF they don't want to cooperate, >> they risk being terminated. >> >> E.g., how many window applications handle an "expose" event? >> Ans: ALL of them -- else their windows don't get drawn! :> > > I know enough tasks which have periods where they don't handle exposeYes, but they have *code* that is intended to handle the event. I.e., the developer doesn't *ignore* it. It is a key part of the API. ---> If you want to draw on the screen, you deal with the expose event. ---> If you want to request "spare" resources, you deal with the "relinquish resource" event.> events. Just use the standard Windows Explorer on a flaky network drive. > I would assume during the same time they won't handle memory-release > requests.That;s a problem with the OS not handling overload gracefully (didn't someone complain that an *RTOS* shouldn't be dealing with the sorts of issues I'm raising? :> )>>> If the set of tasks is wildly variable, under control of the user, you >>> could ask the user to set up resource usage on a per-task basis. After >>> all, the user knows best what the priorities are. >> >> Yes, that is the ultimate goal. I can assign default >> "budgets" to each task and let the user modify those >> (within some range of constraints). The "currency" >> I proposed is one such mechanism. > > Let me check, we're in comp.arch.embedded. What kind of user is this, > and what kind of applications does he run? :-) I'm just asking because > most of the time, "our" products have a system designer who hopefully > knows what he's doing.For a *closed* product, you can "examine all possibilities" and "pick wisely" (at design time). If you open that product up to third party applications/enhancements, then you don't have any control over the quality of the "designers" for those aspects of the resulting system. Hence my desire to come up with a framework that *(en)forces* compliance. And, a way that allows users to intuitively identify the (third party!) aspects of the product that "suck".>> I'm assuming the application developer can. *IF* he is motivated >> to do so (by policies that can make his UNcooperative application >> look like *crap* if he doesn't comply) > > The operating system research group at TU Dresden (where I studied until > seven years ago) is building a real-time operating system based on an L4Yes, years ago I looked into L3.> micro-kernel. I don't know the current status, but their approach was to > model the real-time properties of their hardware (harddisk, graphics > card, etc.), and their applications. Thus, the application says "I need > 1/4 screen space at 25 fps, 5 mbps +/- 1 mbps harddisk transfer, and 200 > MIPS", and some admission control component decides whether that'll work > or not. They didn't use worst-case numbers, but some mathematical > trickery allowing them to model jitter. > > Incidentally, L4's approach for virtual memory is similar to yours: > tasks ask their pager for memory, which the pager gives them, but he has > the right to take it away at any time *without asking*. This means, the > task has to inform the pager *beforehand* what to do with that memory.Hmmm... I think that would be a tougher environment to work in (unless you have backing store). I.e., any reference to a "swappable" page has to be able to deal with a page fault. While the OS can field the fault, the application would then need to decide what to do about it (e.g., if the default pager doesn't swap the page back in). So, if you want to be able to *discard* pages (like me), you would have to surround all references to those pages with code to check for pageouts. E.g., if you have built 10 pages of (sequential) data and are working on page #11, page #3 might get swapped out while you aren't looking at it (and hence won't fault) just as easily as page 11 could. (I suppose you set the handler for those pages to PREVENT pageout -- though that sort of policy would too easily be abused) I think, conceptually, it is easier to be *told*/asked to relinquish resources and then let *you* decide which to release so you subsequently *know* not to reference them.> The usual contract is, of course, "you can take it if you store it in a > page file and give it back when I need it again". But you can implement > other contracts. I don't know if anyone did that.
Applications "buying" resources
Started by ●December 30, 2010
Reply by ●December 31, 20102010-12-31
Reply by ●January 1, 20112011-01-01
On 31/12/10 14:31, D Yuniskis wrote:> Hi Stefan, > > On 12/31/2010 4:52 AM, Stefan Reuther wrote: > > [attributions elided] > >>>>> I agree. The whole idea seems misplaced in an RTOS. The point of a >>>>> /real time/ operating system is that tasks should do what they have to >>>>> do, within the time (and resource) limits they specify. >>>> >>>> Exactly that's what I was thinking. "Real Time" means: given this >>>> set of >>>> resources, and this workload, it will work (at all time) or not. >>> >>> No. Please see my explanation in my reply to David's post. >>> Real-time just means "result has a time-sensitive component". >>> Also, the *scale* of that sensitivity is application specific: >> >> You're just explaining what I shortened to "it will work": whereas a >> batch system will take as long as it takes, a real-time system must >> produce a result within certain time constraints. Those differ between a >> VoIP system and a deep space probe, but the principle is the same. > > No. A real-time system *hopes* to produce a result -- of > some time-valued function -- in some timeframe relative to > a deadline. *But*, failing to meet that deadline *and* > the subsequent "non-zero valuation period" just means the > RT *task* missed it's deadline. That doesn't mean the > "system" is broken. E.g., if you miss an unrecoverable > network packet, then whatever it was used for can't > (typically) be accomplished. But, that doesn't mean that > your application can't continue. If you drop a packet in > a video stream, the image shows some sort of visual > artifact... but, can resume and continue afterwards. > The application doesn't have to terminate or crash. > > The idea that it absolutely *must* work is an over > simplification. >That's just bad specification. A real-time system *must* work. But what you mean by "work" should be correctly specified. For example, for a motor control system, the most important functionality may be to fail in a free-wheeling mode, so that the system can be easily overridden manually. Actually running the motor would then be a lower-priority requirement. Or your video player may have a requirement that it should either show the frame, or drop it, with perhaps a required minimum percentage of shown frames. The ability to drop frames is a feature and part of the specification - it is not a failure. "Failure is always an option" may be a good motto for Mythbusters, but it is a poor way to view real-time systems.
Reply by ●January 1, 20112011-01-01
On 31/12/10 00:37, Jon Kirwan wrote:> Just thought I'd let you know that your worldview is much > closer to mine than David's is. I almost could have written > your words for you. Interesting; and enjoying the discussion > too. > > JonIt all boils down to how you specify a correctly working system. A system that does not work as specified is broken, and a system that you /know/ will not always work as specified, is badly designed. If you want to design a system that will do a particular job most of the time, then that's how you specify it - "in /these/ circumstances, the system will do this job - in other circumstances, it will do something else". You /cannot/ just make software that will work some of the time, and call it a working system! If you want to save resources and make a system that can do A, B and C, but no more than two at a time, then that's your specification. You have very definitely /not/ made a system that can do A, B and C. I don't mean to say that a system should not have parts (or even its whole) working in a "best effort" way. It's unusual to have a system that doesn't have such parts. But they are not real time, and certainly not hard real time, and the rest of the system must be specified and designed with the understanding that those parts may fail.
Reply by ●January 1, 20112011-01-01
Hi, D Yuniskis wrote:> On 12/31/2010 4:52 AM, Stefan Reuther wrote: >>>> Exactly that's what I was thinking. "Real Time" means: given this >>>> set of >>>> resources, and this workload, it will work (at all time) or not. >>> >>> No. Please see my explanation in my reply to David's post. >>> Real-time just means "result has a time-sensitive component". >>> Also, the *scale* of that sensitivity is application specific: >> >> You're just explaining what I shortened to "it will work": whereas a >> batch system will take as long as it takes, a real-time system must >> produce a result within certain time constraints. Those differ between a >> VoIP system and a deep space probe, but the principle is the same. > > No. A real-time system *hopes* to produce a result -- of > some time-valued function -- in some timeframe relative to > a deadline.According to my definition of real-time, it doesn't "hope", but it "knows" or "guarantees". If it just hopes, that's typical best-effort scheduling in a desktop OS. You set your priority high enough and hope to be able to decode all video frames in time, and if you don't manage to do it, you try to compensate. That's at most soft real-time.>> Of course not. But if it's a good telephone company, their switches will >> either accept a connection (that is, they'll have enough computing power >> to run the codec, and enough wire to transport it), or refuse it (giving >> you a busy signal). At least the good ones don't start stuttering when >> the network is overloaded. > > Our telcos are sized for 10-20% usage (I have no idea of cell > capacity). And, have rather loose tolerances on how quickly > they *do* react (e.g., 2 *seconds* for a dialtone).I didn't talk about reaction time or availability. But it has admission control: years ago, you had, say, 100 copper wires in a cable from London to Paris. Which means: 100 people can talk. The 101st gets a busy signal. Now you have one fiber which has bandwith for 100 people. Which means: 100 people can talk, the 101st gets a busy signal. It doesn't try to squeeze a 101st call into that fiber, by asking the others to step aside a bit and downgrade. At least, I hope so (I only buy telephone from companies which offer me unfiltered end-to-end G.711, no "NGN" crap).>>> So, your MP3 decoder spawns a separate task >>> to "decode ahead" so that *it* can have less >>> stringent timing requirements? And, the MP3 >>> decoder then *kills* that task when the CPU >>> needs those cycles? (no, I imagine you >>> wrote your MP3 decoder to always work the same >>> way in the same time in the same footprint) >> >> My software is partitioned into "real-time" and "batch" tasks. The > > Since everything runs on the same scheduler (though potentially > with different scheduling algorithms), all of my tasks are > processed as if real-time. Deadlines and priorities differentiate > between "batch" and "real-time" tasks."batch" tasks are simply tasks with increadibly low priorities, which are executed in round-robin.>>>> Doing something similar with memory is probably not as easy, but has >>>> been done (e.g. Windows 3.0 "discardable memory"). The problem is that >>>> usually the task has to know that the memory is gone, but you can't let >>> >>> That's why you *ask* ^^^^^^^^^ the task to relinquish the resource(s). >> >> But *how* does it ask? > > The same way it handles other asynchronous requests from the > kernel: an exception handler. The kernel can make upcalls to > any task at any time. "How do you SIGHUP a task?" "How do you > tell a task that it has a 'divide by zero' error?"Those do not need timely feedback from the kernel. The kernel just says, "hey, this happened, deal with it."> How do you tell a task that you are unmapping a portion of its > memory?" etc.This one needs feedback.>> Scenario: task A uses "extra memory". Now, task B comes around, asking >> the kernel "hey, I'm important, I need memory". The kernel asks task A >> "hey, give me back some memory". How does it continue? >> - how can task A clean up and call back the kernel, "here, I'm done"? > > The exception handler processes the upcall from the kernel > and does whatever is requested and "returns" the resources > that it can dispose of. I.e., the "signaled" task, more often > than not, is NOT "executing" when the request comes in -- the > executing task is the one that is requesting/requiring the > resource. So, the kernel needs to be able to "interrupt" > the task and cause it to deal with the exception instead of > whatever it was doing at the time.But how does the kernel know that the task is done? How can the task be sure that the kernel knows it cooperates? Let's say I'm making a task that wants to play nice. It has a SIGFREEMEM handler. It goes through my data structures and frees a lot of memory (which is BTW not trivial if it can, like a signal, happen at any time, even within malloc). How can I be sure that I'm being given the time needed to do the cleanup, and not being struck by a kernel timeout just because other tasks ate up the CPU?>> - does the kernel suspend task B until task A answers? Sounds like a >> priority inversion to me. > > Any time you request a service from the kernel, you have to be > prepared for it to NOT succeed. Or, to take a *bounded* amount > of time *to* succeed. So, the service call that task B has > previously made just pends while this happens.My problem is the definition of "while this happens". If it's a timeout provided by task B, it would depend on B whether A works (according to Murphy's law, B of course sets the timeout just one ns too low for A to succeed). If it's a return code "sorry, I have no memory, but I have asked others; please retry later", that'd be polling which is evil[tm]. If it pends B until A calls back, that's priority inversion. Stefan
Reply by ●January 1, 20112011-01-01
Hi, D Yuniskis wrote:> On 12/31/2010 5:04 AM, Stefan Reuther wrote: >> micro-kernel. I don't know the current status, but their approach was to >> model the real-time properties of their hardware (harddisk, graphics >> card, etc.), and their applications. Thus, the application says "I need >> 1/4 screen space at 25 fps, 5 mbps +/- 1 mbps harddisk transfer, and 200 >> MIPS", and some admission control component decides whether that'll work >> or not. They didn't use worst-case numbers, but some mathematical >> trickery allowing them to model jitter. >> >> Incidentally, L4's approach for virtual memory is similar to yours: >> tasks ask their pager for memory, which the pager gives them, but he has >> the right to take it away at any time *without asking*. This means, the >> task has to inform the pager *beforehand* what to do with that memory. > > Hmmm... I think that would be a tougher environment to work in > (unless you have backing store). I.e., any reference to a > "swappable" page has to be able to deal with a page fault. > While the OS can field the fault, the application would then > need to decide what to do about it (e.g., if the default pager > doesn't swap the page back in). So, if you want to be able > to *discard* pages (like me), you would have to surround all > references to those pages with code to check for pageouts. > > E.g., if you have built 10 pages of (sequential) data and are > working on page #11, page #3 might get swapped out while you > aren't looking at it (and hence won't fault) just as easily > as page 11 could.The task would have to tell that the pager. The usual contract is: if you take away my page, you have to give it back to me with the same contents when I need it again. Of course, the application could also tell the pager beforehand: if you take this one instead, you do not need to preserve its content. Or: if you take this one, you do not need to preserve its content, because you can load it from that file ---> over there. Or: if you take this one, please set this flag. That's the point I'm trying to make: it puts the knowledge of which resources are disposable into the same entity which manages the resources. It does not need application code to execute at the time when resources are scarce. To fit into your "buying" model: of course the resource provider can make discardable pages "cheaper" than non-discardable. Like: you can have ten megs with backing store, and twenty without. Stefan
Reply by ●January 1, 20112011-01-01
On Sat, 01 Jan 2011 14:03:44 +0100, David Brown <david.brown@removethis.hesbynett.no> wrote:>On 31/12/10 00:37, Jon Kirwan wrote: >> Just thought I'd let you know that your worldview is much >> closer to mine than David's is. I almost could have written >> your words for you. Interesting; and enjoying the discussion >> too. >> >> Jon > >It all boils down to how you specify a correctly working system. A >system that does not work as specified is broken, and a system that you >/know/ will not always work as specified, is badly designed. If you >want to design a system that will do a particular job most of the time, >then that's how you specify it - "in /these/ circumstances, the system >will do this job - in other circumstances, it will do something else". > >You /cannot/ just make software that will work some of the time, and >call it a working system! If you want to save resources and make a >system that can do A, B and C, but no more than two at a time, then >that's your specification. You have very definitely /not/ made a system >that can do A, B and C. > >I don't mean to say that a system should not have parts (or even its >whole) working in a "best effort" way. It's unusual to have a system >that doesn't have such parts. But they are not real time, and certainly >not hard real time, and the rest of the system must be specified and >designed with the understanding that those parts may fail.I just find my reasoning for using an operating system in my application spaces more closely aligned with DY's arguments. I'm not arguing that there aren't other application spaces that are quite different, or that you are wrong-minded in your own perspective. I'm just enjoying the discussion. Jon
Reply by ●January 1, 20112011-01-01
On 01/01/11 14:57, Jon Kirwan wrote:> On Sat, 01 Jan 2011 14:03:44 +0100, David Brown > <david.brown@removethis.hesbynett.no> wrote: > >> On 31/12/10 00:37, Jon Kirwan wrote: >>> Just thought I'd let you know that your worldview is much >>> closer to mine than David's is. I almost could have written >>> your words for you. Interesting; and enjoying the discussion >>> too. >>> >>> Jon >> >> It all boils down to how you specify a correctly working system. A >> system that does not work as specified is broken, and a system that you >> /know/ will not always work as specified, is badly designed. If you >> want to design a system that will do a particular job most of the time, >> then that's how you specify it - "in /these/ circumstances, the system >> will do this job - in other circumstances, it will do something else". >> >> You /cannot/ just make software that will work some of the time, and >> call it a working system! If you want to save resources and make a >> system that can do A, B and C, but no more than two at a time, then >> that's your specification. You have very definitely /not/ made a system >> that can do A, B and C. >> >> I don't mean to say that a system should not have parts (or even its >> whole) working in a "best effort" way. It's unusual to have a system >> that doesn't have such parts. But they are not real time, and certainly >> not hard real time, and the rest of the system must be specified and >> designed with the understanding that those parts may fail. > > I just find my reasoning for using an operating system in my > application spaces more closely aligned with DY's arguments. > I'm not arguing that there aren't other application spaces > that are quite different, or that you are wrong-minded in > your own perspective. I'm just enjoying the discussion. >It is possible to argue that this is all shades of grey, and it's a matter of emphasis. After all, it is true that a real-time system must do it's best in the face of problems, such as hardware failures - and you /could/ say that "lack of resources" is just another such failure. But this thread has been about "real-time" systems from the start - you simply don't design a real-time system with such lack-of-resource failures. Such a system is all about guarantees - /if/ there are no hardware failures, then the system /will/ work. You can use operating systems for other purposes too, such as to mediate between different best-effort tasks - but that is not real-time.
Reply by ●January 1, 20112011-01-01
On Sat, 01 Jan 2011 15:13:34 +0100, David Brown <david.brown@removethis.hesbynett.no> wrote:>On 01/01/11 14:57, Jon Kirwan wrote: >> On Sat, 01 Jan 2011 14:03:44 +0100, David Brown >> <david.brown@removethis.hesbynett.no> wrote: >> >>> On 31/12/10 00:37, Jon Kirwan wrote: >>>> Just thought I'd let you know that your worldview is much >>>> closer to mine than David's is. I almost could have written >>>> your words for you. Interesting; and enjoying the discussion >>>> too. >>>> >>>> Jon >>> >>> It all boils down to how you specify a correctly working system. A >>> system that does not work as specified is broken, and a system that you >>> /know/ will not always work as specified, is badly designed. If you >>> want to design a system that will do a particular job most of the time, >>> then that's how you specify it - "in /these/ circumstances, the system >>> will do this job - in other circumstances, it will do something else". >>> >>> You /cannot/ just make software that will work some of the time, and >>> call it a working system! If you want to save resources and make a >>> system that can do A, B and C, but no more than two at a time, then >>> that's your specification. You have very definitely /not/ made a system >>> that can do A, B and C. >>> >>> I don't mean to say that a system should not have parts (or even its >>> whole) working in a "best effort" way. It's unusual to have a system >>> that doesn't have such parts. But they are not real time, and certainly >>> not hard real time, and the rest of the system must be specified and >>> designed with the understanding that those parts may fail. >> >> I just find my reasoning for using an operating system in my >> application spaces more closely aligned with DY's arguments. >> I'm not arguing that there aren't other application spaces >> that are quite different, or that you are wrong-minded in >> your own perspective. I'm just enjoying the discussion. >> > >It is possible to argue that this is all shades of grey, and it's a >matter of emphasis. After all, it is true that a real-time system must >do it's best in the face of problems, such as hardware failures - and >you /could/ say that "lack of resources" is just another such failure. >But this thread has been about "real-time" systems from the start -I thought it was about DY's RTOS.>you >simply don't design a real-time system with such lack-of-resource >failures. Such a system is all about guarantees - /if/ there are no >hardware failures, then the system /will/ work. You can use operating >systems for other purposes too, such as to mediate between different >best-effort tasks - but that is not real-time.I think you are just arguing, now, when I wasn't wanting to. So, okay: I use an operating system for software partitioning, simplicity of design, and flexibility for future change. I generally do applications where EVERYTHING COUNTS, though. DY's comments about those making a customer pay more than they otherwise have to (in terms of excess hardware costs, size, battery/power usage, heat, lower precision or repeatability, etc) is about where I'm at. All corners in my application space count. I don't want to make a customer pay for 256k flash parts when 8k would have done had I avoided linking in STL, nor do I want to "accept" for the customer a 5mA average draw in a battery application when 200uA is sufficient for the same job. Of course, the application has to work. That's given. Since everything I do is instrumentation, real time is also a given. As is precision of measurement sampling. Where appropriate, I will go to great lengths to ensure that measurement variation is zero clock cycles. Meaning that I don't even allow any variation of interrupt latency and will select a micro that can guarantee that or else arrange the design to avoid it, if needed. The operating system and threads in it will be arranged to support that with absolute precision. Operating systems that are targeted at wider audiences generally cannot address my needs very well. I may have selected a micro with 128 bytes of RAM... total. And need 100 of it for the application, leaving 28 for the O/S and the three threads needing support for sleep and semaphore queues. Just as an example that isn't too far from what might take place. Jon
Reply by ●January 1, 20112011-01-01
On 12/30/2010 1:43 AM, D Yuniskis wrote:> What I would like is a scheme whereby applications can decide > how much the resources they are holding are "worth". And, > then "buy" those resources (with some sort of constrained > "purse"). This gives the "kernel" a bit more flexibility > in handling resource reallocation -- e.g., *it* sets the > current price for the resources and can change that price > dynamically to "entice" tasks to shed resources (by making > it increasingly expensive to hold onto them)Don, I suggest focusing on the real-world cost of shedding resources. If a tasks yields 100 kB of memory, what is the cost to the user -- an extra 300 ms response time, perhaps? The manager may say "I'm willing to accept 1000 ms additional delay, how much memory can you release for me?" -- Thad
Reply by ●January 1, 20112011-01-01
Hi Stefan, On 1/1/2011 6:20 AM, Stefan Reuther wrote:> D Yuniskis wrote: >> On 12/31/2010 5:04 AM, Stefan Reuther wrote: >>> micro-kernel. I don't know the current status, but their approach was to >>> model the real-time properties of their hardware (harddisk, graphics >>> card, etc.), and their applications. Thus, the application says "I need >>> 1/4 screen space at 25 fps, 5 mbps +/- 1 mbps harddisk transfer, and 200 >>> MIPS", and some admission control component decides whether that'll work >>> or not. They didn't use worst-case numbers, but some mathematical >>> trickery allowing them to model jitter. >>> >>> Incidentally, L4's approach for virtual memory is similar to yours: >>> tasks ask their pager for memory, which the pager gives them, but he has >>> the right to take it away at any time *without asking*. This means, the >>> task has to inform the pager *beforehand* what to do with that memory. >> >> Hmmm... I think that would be a tougher environment to work in >> (unless you have backing store). I.e., any reference to a >> "swappable" page has to be able to deal with a page fault. >> While the OS can field the fault, the application would then >> need to decide what to do about it (e.g., if the default pager >> doesn't swap the page back in). So, if you want to be able >> to *discard* pages (like me), you would have to surround all >> references to those pages with code to check for pageouts. >> >> E.g., if you have built 10 pages of (sequential) data and are >> working on page #11, page #3 might get swapped out while you >> aren't looking at it (and hence won't fault) just as easily >> as page 11 could. > > The task would have to tell that the pager. The usual contract is: if > you take away my page, you have to give it back to me with the same > contents when I need it again.Understood. That's easy to implement: the kernel (or its agent) takes the page, marks it as "missing", then when/if the task tries to access it, faults a (possibly new/different) page in, fills it from backing store and resumes the "interrupted" task.> Of course, the application could also tell the pager beforehand: if you > take this one instead, you do not need to preserve its content. Or: if > you take this one, you do not need to preserve its content, because you > can load it from that file ---> over there. Or: if you take this one, > please set this flag.But, think of *that* scenario: the kernel (or its agent) takes the page, marks it as "missing", then when/if the task tries to access it, page fault allows the access to be completed (with bogus data) and the expectation that the task will "notice" that a flag indicates the data should be ignored (?)> That's the point I'm trying to make: it puts the knowledge of which > resources are disposable into the same entity which manages the > resources. It does not need application code to execute at the time when > resources are scarce.Understood. There is potential for BIG WIN in that approach. I'm just trying to think through real world code and how it would handle this (brain is fuzzy as I have been up all night babysitting the citrus :< ).> To fit into your "buying" model: of course the resource provider can > make discardable pages "cheaper" than non-discardable. Like: you can > have ten megs with backing store, and twenty without.Let me back up. Some portion of a task's memory is wired down. I.e., it *knows* that it has this memory, guaranteed (all or nothing -- if the task is killed, it loses everything). [I recognize your idea can be extended to cover this case as well] Beyond that, some varying amount could be "surplus resources" that it has acquired at various times. It may add or subtract from this freely throughout its execution. In addition to the above "notification" problem (I think I can solve that using the same exception handler mechanism and just have the kernel's page fault handler "complete the memory access" with bogus results -- this works OK for everything but *code* execution from a "forfeitable resource"), you also need a way of letting the kernel know which pages "take first". Returning to the MP3 example, if pages 3, 9 and 11 contain the decoded output for seconds N, N+1 and N+2 of UPCOMING audio, then the MP3 task wants them to be "taken" (forfeit) in the order 11, 9, 3. Any other order effectively renders the remaining pages useless (or, "less useful"). One idea that comes to mind is to tag each page with the "price paid" (Robert's Dutch auction). No, that's probably not right (because what you paid for it might not reflect what it is currently worth... e.g., page 3 is worth more than page 11 *now*. Yet, when you bought page 3, you might have paid less for it because page *2* -- which has since been discarded -- was more valuable). But, the idea trying to take hold in my sluggish brain makes sense -- tell the kernel what the page is worth so it can make that decision on my behalf without my involvement. Note that my idea of letting the kernel NOTIFY the task allows the task to make that value decision AT THAT INSTANT instead of having to keep appraising the kernel of changing values... And, of course, all of this is predicated on using VM to move the resources around. (it wouldn't extend to a flat, nonpaged memory model). I think I need some sleep. Wonderful. I get to dream about memory allocations... :-/