Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.realtime > #174 > unrolled thread
| Started by | Don Y <this@isnotme.com> |
|---|---|
| First post | 2013-07-25 12:23 -0700 |
| Last post | 2013-08-02 07:26 -0700 |
| Articles | 20 on this page of 73 — 12 participants |
Back to article view | Back to comp.realtime
Resource revocation Don Y <this@isnotme.com> - 2013-07-25 12:23 -0700
Re: Resource revocation Paul Rubin <no.email@nospam.invalid> - 2013-07-25 12:51 -0700
Re: Resource revocation Don Y <this@isnotme.com> - 2013-07-25 15:00 -0700
Re: Resource revocation Paul Rubin <no.email@nospam.invalid> - 2013-07-25 19:38 -0700
Re: Resource revocation Don Y <this@isnotme.com> - 2013-07-25 22:12 -0700
Re: Resource revocation Paul Rubin <no.email@nospam.invalid> - 2013-07-25 23:37 -0700
Re: Resource revocation Don Y <this@isnotme.com> - 2013-07-26 01:13 -0700
Re: Resource revocation Paul Rubin <no.email@nospam.invalid> - 2013-07-26 02:48 -0700
Re: Resource revocation Don Y <this@isnotme.com> - 2013-07-26 04:19 -0700
Re: Resource revocation Paul Rubin <no.email@nospam.invalid> - 2013-07-26 09:46 -0700
Re: Resource revocation Don Y <this@isnotme.com> - 2013-07-26 10:21 -0700
Re: Resource revocation Hans-Bernhard Bröker <HBBroeker@t-online.de> - 2013-07-26 19:25 +0200
Re: Resource revocation Paul Rubin <no.email@nospam.invalid> - 2013-07-26 10:51 -0700
Does the Buddha have a real time nature? ;) (was Resource revocation) Roberto Waltman <usenet@rwaltman.com> - 2013-07-26 17:06 -0400
Re: Does the Buddha have a real time nature? ;) (was Resource revocation) Don Y <this@isnotme.com> - 2013-07-26 17:12 -0700
Re: Does the Buddha have a real time nature? ;) (was Resource revocation) Tom Gardner <spamjunk@blueyonder.co.uk> - 2013-07-27 09:45 +0100
Re: Does the Buddha have a real time nature? ;) (was Resource revocation) Don Y <this@isnotme.com> - 2013-07-27 12:28 -0700
Re: Does the Buddha have a real time nature? ;) (was Resource revocation) Hans-Bernhard Bröker <HBBroeker@t-online.de> - 2013-07-27 14:11 +0200
Re: Resource revocation Don Y <this@isnotme.com> - 2013-07-26 12:00 -0700
Re: Resource revocation stephenXXX@mpeforth.com (Stephen Pelc) - 2013-07-27 16:49 +0000
Re: Resource revocation Richard Damon <Richard@Damon-Family.org> - 2013-07-28 18:31 -0400
Re: Resource revocation Don Y <this@isnotme.com> - 2013-07-28 15:51 -0700
Re: Resource revocation Richard Damon <Richard@Damon-Family.org> - 2013-07-28 20:12 -0400
Re: Resource revocation Don Y <this@isnotme.com> - 2013-07-28 18:35 -0700
Re: Resource revocation Richard Damon <Richard@Damon-Family.org> - 2013-07-29 00:10 -0400
Re: Resource revocation Don Y <this@isnotme.com> - 2013-07-29 00:23 -0700
Re: Resource revocation Paul Rubin <no.email@nospam.invalid> - 2013-07-29 01:05 -0700
Re: Resource revocation Don Y <this@isnotme.com> - 2013-07-29 12:07 -0700
Re: Resource revocation upsidedown@downunder.com - 2013-07-30 01:11 +0300
Re: Resource revocation Don Y <this@isnotme.com> - 2013-07-29 15:20 -0700
Re: Resource revocation Rob Gaddi <rgaddi@technologyhighland.invalid> - 2013-07-29 15:42 -0700
Re: Resource revocation Don Y <this@isnotme.com> - 2013-07-29 16:41 -0700
Re: Resource revocation upsidedown@downunder.com - 2013-07-30 08:51 +0300
Re: Resource revocation Tom Gardner <spamjunk@blueyonder.co.uk> - 2013-07-30 09:09 +0100
Re: Resource revocation Don Y <this@isnotme.com> - 2013-07-30 01:30 -0700
Re: Resource revocation Tom Gardner <spamjunk@blueyonder.co.uk> - 2013-07-30 10:04 +0100
Re: Resource revocation Paul Rubin <no.email@nospam.invalid> - 2013-07-30 02:55 -0700
Re: Resource revocation Don Y <this@isnotme.com> - 2013-07-30 07:12 -0700
Re: Resource revocation Tom Gardner <spamjunk@blueyonder.co.uk> - 2013-07-30 16:59 +0100
Re: Resource revocation Don Y <this@isnotme.com> - 2013-07-30 13:17 -0700
Re: Resource revocation Paul Rubin <no.email@nospam.invalid> - 2013-07-30 10:12 -0700
Re: Resource revocation Tom Gardner <spamjunk@blueyonder.co.uk> - 2013-07-30 18:48 +0100
Re: Resource revocation Don Y <this@isnotme.com> - 2013-07-30 20:18 -0700
Re: Resource revocation upsidedown@downunder.com - 2013-07-31 09:27 +0300
Re: Resource revocation [long] Don Y <this@isnotme.com> - 2013-07-31 00:47 -0700
Re: Resource revocation Paul Rubin <no.email@nospam.invalid> - 2013-07-30 02:50 -0700
Re: Resource revocation upsidedown@downunder.com - 2013-07-30 13:22 +0300
Re: Resource revocation Don Y <this@isnotme.com> - 2013-07-30 07:24 -0700
Re: Resource revocation Don Y <this@isnotme.com> - 2013-07-30 01:17 -0700
Re: Resource revocation Paul Rubin <no.email@nospam.invalid> - 2013-07-29 19:28 -0700
Re: Resource revocation upsidedown@downunder.com - 2013-07-29 11:40 +0300
Re: Resource revocation Don Y <this@isnotme.com> - 2013-07-29 11:44 -0700
Re: Resource revocation Tom Gardner <spamjunk@blueyonder.co.uk> - 2013-07-29 20:56 +0100
Re: Resource revocation Don Y <this@isnotme.com> - 2013-07-29 13:16 -0700
Re: Resource revocation Richard Damon <Richard@Damon-Family.org> - 2013-07-30 00:08 -0400
Re: Resource revocation Don Y <this@isnotme.com> - 2013-07-30 23:41 -0700
Re: Resource revocation Paul Rubin <no.email@nospam.invalid> - 2013-07-31 00:58 -0700
Re: Resource revocation Paul Rubin <no.email@nospam.invalid> - 2013-07-31 10:18 -0700
Re: Resource revocation George Neuner <gneuner2@comcast.net> - 2013-08-02 06:19 -0400
Re: Resource revocation Richard Damon <Richard@Damon-Family.org> - 2013-08-03 02:26 -0400
Re: Resource revocation Paul Rubin <no.email@nospam.invalid> - 2013-07-28 19:31 -0700
Re: Resource revocation Don Y <this@isnotme.com> - 2013-07-29 00:44 -0700
Re: Resource revocation Richard Damon <Richard@Damon-Family.org> - 2013-07-25 22:42 -0400
Re: Resource revocation Don Y <this@isnotme.com> - 2013-07-25 22:12 -0700
Re: Resource revocation "Boudewijn Dijkstra" <sp4mtr4p.boudewijn@indes.com> - 2013-07-31 13:41 +0200
Re: Resource revocation Don Y <this@isnotme.com> - 2013-07-31 07:51 -0700
Re: Resource revocation Don Y <this@isnotme.com> - 2013-07-31 08:07 -0700
Re: Resource revocation Anders.Montonen@kapsi.spam.stop.fi.invalid - 2013-07-31 15:55 +0000
Re: Resource revocation Don Y <this@isnotme.com> - 2013-07-31 10:18 -0700
Re: Resource revocation "Boudewijn Dijkstra" <sp4mtr4p.boudewijn@indes.com> - 2013-08-01 14:42 +0200
Re: Resource revocation Don Y <this@isnotme.com> - 2013-08-01 14:34 -0700
Re: Resource revocation upsidedown@downunder.com - 2013-08-02 09:08 +0300
Re: Resource revocation Don Y <this@isnotme.com> - 2013-08-02 07:26 -0700
Page 1 of 4 [1] 2 3 4 Next page →
| From | Don Y <this@isnotme.com> |
|---|---|
| Date | 2013-07-25 12:23 -0700 |
| Subject | Resource revocation |
| Message-ID | <ksrtvv$kmp$1@speranza.aioe.org> |
Hi, What's the current "best practices" regarding asynchronous notifications (in a multithreaded environment)? I have a system wherein "tasks" (omit a formal definition) request resources from a service that meters out their use; waiting until the resource has been granted to them "officially" (in some cases, this is all trust based). When done, they surrender the resource to the service where it can be reused by other consumers. But, there are times when the service must revoke a granted use of a particular resource. In some cases, it "asks" for the resource back (giving the current consumer time to tidy up before releasing it). In other cases, it just *seizes* the resource -- and notifies the consumer after-the-fact. Presently, I use signals to notify the consumer when this sort of thing is happening. But, my personal experience is such that folks have problems writing this sort of code. *Remembering* that they have to register a handler for the signal; remembering that said handler can be invoked at any time (including immediately after it has been registered); etc. Is there a new "safer" way of implementing these types of notifications? Thx, --don
[toc] | [next] | [standalone]
| From | Paul Rubin <no.email@nospam.invalid> |
|---|---|
| Date | 2013-07-25 12:51 -0700 |
| Message-ID | <7xehame7ut.fsf@ruckus.brouhaha.com> |
| In reply to | #174 |
Don Y <this@isnotme.com> writes: > What's the current "best practices" regarding asynchronous > notifications (in a multithreaded environment)? It would help if you specified the OS, the programming language, etc. > Presently, I use signals to notify the consumer Ugh!!! > Is there a new "safer" way of implementing these types of > notifications? You might find this interesting: http://jlouisramblings.blogspot.com/2012/08/getting-25-megalines-of-code-to-behave.html
[toc] | [prev] | [next] | [standalone]
| From | Don Y <this@isnotme.com> |
|---|---|
| Date | 2013-07-25 15:00 -0700 |
| Message-ID | <kss75t$dgh$1@speranza.aioe.org> |
| In reply to | #175 |
Hi Paul,
On 7/25/2013 12:51 PM, Paul Rubin wrote:
> Don Y <this@isnotme.com> writes:
>> What's the current "best practices" regarding asynchronous
>> notifications (in a multithreaded environment)?
>
> It would help if you specified the OS, the programming language, etc.
Nothing that you would be familiar with. I don't see how reliance on
a particular language keyword or OS hook would matter when considering
the way in which this *functionality* is availed to the developer.
I.e., do you require the developer to *poll* for the asynchronous
revocation of the resource? Do you kill the consuming thread? Do
you let him think he still has the resource and force him to *verify*
this "at the end"? Do you trap when he accesses it after it has
been revoked (how to notify of the trap?!) etc. (see below)
Assume support for threads. This implies a means by which they can
intercommunicate. And, that more than one "execution context" can
coexist. The question is, how do you *divert* execution to a
"different thread" (or subthread) based on some developer defined
constraint (that some other piece of code in the system is implementing)
>> Presently, I use signals to notify the consumer
>
> Ugh!!!
The beauty of signals is they have a history (so those of us who know
how to use them properly aren't wondering how they work or what their
pitfalls are). And, they offer a plethora of different mechanisms
by which the developer can *handle* the signal (including deferring it
*or* ignoring it!).
The biggest problem is for folks who forget to code for the
possibilities that the signals are meant to guard against.
E.g., akin to folks not knowing how to implement atomic operations,
forgetting that malloc() can return NULL (or that the region returned
can be LARGER than that requested), etc.
But, there are noticeable differences (and attendant risk) with each
of the following *different* "stylistic" approaches to the problem:
-----------
handle = await_resource(resource_required) // block until available
... // use resource
result=release_resource(handle) // formally relinquish it
if (result == you_didnt_STILL_own_it)
// resource was revoked some time while I thought I owned it
-----------
handle = await_resource(resource_required)
spawn(use_resource) // spawn a thread to do the actual work
await_release(handle)
if (flag_from_thread == my_child_released_it)
// success
else
// someone revoked it!
-----------
do {
result = attempt_resource(resource_required) // try to acquire
if (result == sorry_charlie)
// do something while waiting for resource -- or spin
else
// stop any thumb twiddling you may have started
while (result == sorry_charlie)
while (I_still_own_resource) {
// use the resource
}
if (I_finished_correctly)
release_resource
// success
else
// I must have lost resource somewhere along the line
-----------
register_handler(resource_revoked) // asynchronous handler
handle = await_resource(resource_required) // block until available
... // use resource
if (handler_was_invoked)
// did not finish as planned
else
result=release_resource(handle) // formally relinquish it
-----------
or, even a case where the handler unceremoniously/asynchronously
terminates the consumer thread! (i.e., some *other* thread can
simply monitor to see if that thread has finished its task!)
Do you err on the side of giving the developer as much *rope* as
he wants ("Now, this is how you tie a hangman's knot...") or do
you force him to handle these sorts of things in a predefined
manner -- and adapt his *problem* to your "solution"?
In the latter case, you presumably can attest to your "solution"
being *safer* than other options (however you define safe).
>> Is there a new "safer" way of implementing these types of
>> notifications?
>
> You might find this interesting:
>
> http://jlouisramblings.blogspot.com/2012/08/getting-25-megalines-of-code-to-behave.html
I didn't see anything in there germane to my question. Did I miss
something? As to "how to build robust systems", most of that is old
news...
--don
[toc] | [prev] | [next] | [standalone]
| From | Paul Rubin <no.email@nospam.invalid> |
|---|---|
| Date | 2013-07-25 19:38 -0700 |
| Message-ID | <7xr4emjbaq.fsf@ruckus.brouhaha.com> |
| In reply to | #176 |
Don Y <this@isnotme.com> writes: > I don't see how reliance on a particular language keyword or OS hook > would matter when considering the way in which this *functionality* is > availed to the developer. Different languages and OS's lend themselves to different styles. The application's requirements also matter. E.g. the Erlang approach to infrequent failures (which this resource being preempted might amount to) is to just let the failing process crash, and restart it through supervision. That might not be ok if you can't tolerate a few milliseconds of delay doing that stuff now and then. > But, there are noticeable differences (and attendant risk) with each > of the following *different* "stylistic" approaches to the problem: > ... Most of those don't seem to handle the issue of the resource being preempted while the process in question is trying to use it. >> http://jlouisramblings.blogspot.com/2012/08/getting-25-megalines-of-code-to-behave.html > I didn't see anything in there germane to my question. Did I miss > something? I don't know if you missed anything. The article suggests uses message passing for concurrency. In that scheme, each task typically is organized as a synchronous event loop where each pass through the loop happens rather quickly. In that situation, resource preemption can just be a matter of sending a message saying the process with the resource must be released. Most of my stuff is coded in that style these days. One drawback is that it tends to use more threads than a traditional approach would, so there is a memory and context switching cost. I don't know if that's an issue for you. It does seem easier (at least to me) to keep stuff straight with this approach, with fewer ways to go wrong. Or, as you say, you can just kill the target process, in which case it helps if the OS or runtime environment automatically reclaims the resource you wanted. Again under Erlang, the runtime has a nice framework for restarting killed processes. You could have a priority queue of processes waiting to acquire the resource. So if the resource must be preempted, the preempting process puts in a high priority request, then kills the process with the resource, which (on restart) tries to get the resource back, but (since it has lower priority) it has to wait for the preempting process to finish.
[toc] | [prev] | [next] | [standalone]
| From | Don Y <this@isnotme.com> |
|---|---|
| Date | 2013-07-25 22:12 -0700 |
| Message-ID | <kst0gh$208$2@speranza.aioe.org> |
| In reply to | #177 |
Hi Paul, On 7/25/2013 7:38 PM, Paul Rubin wrote: > Don Y <this@isnotme.com> writes: >> I don't see how reliance on a particular language keyword or OS hook >> would matter when considering the way in which this *functionality* is >> availed to the developer. > > Different languages and OS's lend themselves to different styles. The > application's requirements also matter. E.g. the Erlang approach to > infrequent failures (which this resource being preempted might amount > to) is to just let the failing process crash, and restart it through > supervision. That might not be ok if you can't tolerate a few > milliseconds of delay doing that stuff now and then. On the other hand, it might be acceptable for the task to *think* it still owns the resource and have it "waste" CPU acting on that misbelief. That's why I tried to show different approaches to handling such a notification (and.or deferring action on it). >> But, there are noticeable differences (and attendant risk) with each >> of the following *different* "stylistic" approaches to the problem: >> ... > > Most of those don't seem to handle the issue of the resource being > preempted while the process in question is trying to use it. Right! The way a signal approaches the problem typically avoids this -- it is a true asynchronous notification that "interrupts" the task's normal execution sequence. Though how the *real* task responds to the handler's actions (e.g., the handler may simply set a flag that the "real" algorithm simply examines when convenient) >>> http://jlouisramblings.blogspot.com/2012/08/getting-25-megalines-of-code-to-behave.html > >> I didn't see anything in there germane to my question. Did I miss >> something? > > I don't know if you missed anything. The article suggests uses message > passing for concurrency. In that scheme, each task typically is > organized as a synchronous event loop where each pass through the loop > happens rather quickly. In that situation, resource preemption can just > be a matter of sending a message saying the process with the resource > must be released. Everything in my system is message based (since "tasks" and resources and ... can all be located on different physical processors, message passing makes the most sense). Signals are even delivered in this way (sort of like a high priority message passed to the *scheduler* on a node) > Most of my stuff is coded in that style these days. One drawback is > that it tends to use more threads than a traditional approach would, so > there is a memory and context switching cost. Yes. Everything has the weight of a system call, effectively. "No free lunch". > I don't know if that's an > issue for you. It does seem easier (at least to me) to keep stuff > straight with this approach, with fewer ways to go wrong. Exactly. And, makes things a sh*tload easier to debug (especially in a distributed application) > Or, as you say, you can just kill the target process, in which case it > helps if the OS or runtime environment automatically reclaims the > resource you wanted. Well, the "resource" in question has already been passed along to someone else. So, its more a question of do you let the task continue to consume *other* resources in the mistaken belief that it still owns the significant resource? Or, do you cut your losses now? (Or, do you let the task figure out what has happened AT ITS CONVENIENCE and adopt its own strategy to handling that?) > Again under Erlang, the runtime has a nice > framework for restarting killed processes. You could have a priority > queue of processes waiting to acquire the resource. So if the resource > must be preempted, the preempting process puts in a high priority > request, then kills the process with the resource, which (on restart) > tries to get the resource back, but (since it has lower priority) it has > to wait for the preempting process to finish. Yes, but this approach assumes there are no associated activities that must be unwound. I.e., that everything the task has done can be discarded and recreated. Imagine if the task is machining a piece of metal and the resource that it wanted has been withdrawn. A timely notification of this would allow the task to possibly recover and attempt to reacquire the resource -- instead of having to discard the "work in process" (a slab of metal). Or, the task could checkpoint its progress ON DEMAND (instead of continually) so that it can return to the point at which it was operating when the resource vanished. The "advantage" to an asynchronous notification *like* a signal is it gives the developer as much rope as he wants in deciding how to best recover from that potential problem. The *disadvantage* is he can quickly hang himself by doing something (or failing to do something) wrong. The problem lies in the nature of asynchronous events and how we think of them as developers. While they *can* occur at any time, we tend to only *think* of them occurring at "key points" in our code. E.g., after a multibyte object has been completely updated; not *during* it's update, etc. The other half of this is that it is REALLY HARD to test for these things. You can't just inject an asynchronous event at every possible place where it could occur and verify proper operation. :( Then, their are the timeliness aspects of its assertion and its handling... <frown> I.e., there is a strong (personal) inclination to make the manner in which these situations are handled fit some mold so they are all handled in a similar fashion that *minimizes* problems. But, I really dislike telling people they "can't run with scissors" -- since those folks who are adept at doing so shouldn't be penalized by the "clumsiness" of those who can't! --don
[toc] | [prev] | [next] | [standalone]
| From | Paul Rubin <no.email@nospam.invalid> |
|---|---|
| Date | 2013-07-25 23:37 -0700 |
| Message-ID | <7xbo5pbzdy.fsf@ruckus.brouhaha.com> |
| In reply to | #180 |
Don Y <this@isnotme.com> writes: > On the other hand, it might be acceptable for the task to *think* > it still owns the resource and have it "waste" CPU acting on that > misbelief. This type of program typically doesn't compute very much. It's either acting on some message, or sleeping til the next message arrives. I think overall it's preferable to not confuse the issue by moving stuff around between processes without the processes knowing. The resource should be under control of one process, and relinquished by 1) sending a message asking for the process to give it back; or 2) killing the process, preferably with automatic cleanup actions when the process dies. > Everything in my system is message based ... Signals > are even delivered in this way OK, the usual sense of signals that I thought was reflected in your code sample, is basically delivering a simulated hardware interrupt to a running task, so it needs locks, critical sections and all that messy stuff. > Yes. Everything has the weight of a system call, effectively. In the case of your lawn sprinkler application I think that is fine. IMHO in this day and age, it's only worth dealing with low-level approaches if you're doing hard-real-time or have to run on 10-cent processors or something like that. > Well, the "resource" in question has already been passed along > to someone else. Yeah, the way I'm imagining, I wouldn't do it that way, as described above. > So, its more a question of do you let the task continue to consume > *other* resources in the mistaken belief that it still owns the > significant resource? In this case I'd say just kill the task, so it can restart in a completely known state. Admittedly I am somewhat under the influence of Erlang right now, and this is a core tenet of Erlang philosophy. > Yes, but this approach assumes there are no associated activities > that must be unwound. I.e., that everything the task has done > can be discarded and recreated. The task would periodically post updates saying how far it has gotten (how much water has been dispensed, or whatever). When it's killed and restarts, it can take up where it left off. > Imagine if the task is machining a piece of metal and the resource > that it wanted has been withdrawn. I don't understand this example--what would the "resource" be? In general terms I'd say kill the process and let the crash handler park the tool in a safe position. But in this machining example, I'm imagining some kind of low level PID loop that would keep checking a flag to know if it had to bail out. In either case, the idea is to get to a place where you can restart later. > The "advantage" to an asynchronous notification *like* a signal is > it gives the developer as much rope as he wants The only reason for such "rope" is to push the limits of the hardware because more modular approaches are too slow or whatever. Computers are ridiculously powerful these days, so unless you're doing something extremely demanding (basically something that would have been impossible or economically unfeasible 10 years ago), seeking "rope" is probably a sign of doing something wrong. > The problem lies in the nature of asynchronous events and how > we think of them as developers. Right, they are messy and it's preferable to avoid them. E.g. by using message passing instead of signals. > The other half of this is that it is REALLY HARD to test for these > things. You can't just inject an asynchronous event at every possible > place where it could occur and verify proper operation. :( You should probably look into model-checking tools if you absolutely have to pursue this approach. Dawson Engler's papers on using such tools to find crash bugs in Unix file systems might be of interest. Actually Tom Hawkins' "ImProve" program might be of some use to check that you got all your watering stuff right, in terms of turning correct combinations of valves on and off etc., if you're interested in experimenting with high-tech approaches. I haven't used it but have been interested in it for a while: https://github.com/tomahawkins/improve/wiki/ImProve I did play around with Atom (a hard realtime DSL written by the same guy) and I think the approach is pretty powerful. > I really dislike telling people they "can't run with scissors" -- > since those folks who are adept at doing so shouldn't be penalized by > the "clumsiness" of those who can't! Even someone capable of running with scissors without stabbing himself every time shouldn't do it outside of some dire emergency. In this watering application you have (presumably) rather loose timing constraints, and roughly unlimited CPU resources. So I think you can do fine using safe, simple methods instead of running with scissors.
[toc] | [prev] | [next] | [standalone]
| From | Don Y <this@isnotme.com> |
|---|---|
| Date | 2013-07-26 01:13 -0700 |
| Message-ID | <kstb45$s25$1@speranza.aioe.org> |
| In reply to | #181 |
Hi Paul,
On 7/25/2013 11:37 PM, Paul Rubin wrote:
> Don Y <this@isnotme.com> writes:
>> On the other hand, it might be acceptable for the task to *think*
>> it still owns the resource and have it "waste" CPU acting on that
>> misbelief.
>
> This type of program typically doesn't compute very much. It's either
> acting on some message, or sleeping til the next message arrives.
Actually, the irrigation program "computes" a fair amount, given
how "slow" it is expected to operate. E.g., it has to identify
the "plants" ("water consumers") that are serviced by its zone;
identify their individual water needs; identify the "emitters"
that service their respective root systems and the flow rates
associated with each of those emitters; track the water available
to them "recently" (rainfall, water from other nearby irrigation
zones that happen to overlap their root systems, supplemental water
"injected" by the user manually; etc.); the amount of sunshine
falling on them (some might be shaded during some seasons while
others are in "full/reflected sun") as well as the desicating (sp?)
effects of the wind (again, noting the individual "exposure" to
wind from particular directions; etc.
And, it has to continue to update these data while waiting for
the "water resource". Or, waiting for its *return* (if it has
been revoked). Along the way, it may have to escalate its
request as the *hard* deadline approaches. ("Hey, if you don't
let me water these things soon, they will die -- in which case,
there is no point in my continuing to execute as a task!")
[I.e., this is a soft realtime problem layered inside a hard realtime
shell. There *is* a point where a missed dealine results in a failure]
> I think overall it's preferable to not confuse the issue by moving stuff
> around between processes without the processes knowing.
The question becomes one of whether you inform the process *before*
you take action (or, even let the process itself "relinquish" the
resource) or, if you inform the process after-the-fact. (or, if you
just kill the process and don't even worry about informing it! :> )
> The resource
> should be under control of one process, and relinquished by 1) sending a
> message asking for the process to give it back; or 2) killing the
> process, preferably with automatic cleanup actions when the process
> dies.
If you "request" the process to relinquish the resource, then the
system (i.e., all other consumers of that resource) are at the
mercy of the developer who coded that application. If he fails to
relinquish it (perhaps even failing to notice the notification!)
or intentionally delays relinquishing it (like a youngster trying
to postpone bed-time), then other consumers suffer.
I.e., if everyone adopts that sort of attitude, then you've got
a sluggish system.
And, you *still* would need a kill switch so a stubborn consumer
could be forced to relinquish the resource, regardless of his wishes.
[Note this all ignores the timeliness issues involved. How *quickly*
must a task relinquish a resource when commanded? What happens if the
task isn't a high enough priority to even be granted a significant
slice of the CPU to process that request?]
I've taken the other approach. A process owns (permanently?) the
resources. It then doles them out, on request, to other consumers.
When it wants/needs to give the resource to another consumer, it
does so -- and notifies the previous owner that it has LOST the
resource. (of course, it can also *request* a current consumer
to release a resource... but, it has to be capable of withdrawing
them in the presence of uncooperative consumers!)
This allows me to ensure "policy" over how a resource is managed
is centralized in one place: the (permanent) "owner" of the resource.
Ponder:
We don't notify a task that we are going to take the *CPU* away from
it (timeslice) and expect the task to respond, "OK, you can have it".
Instead, we just *take* the processor and give it to <whatever>
*we* (scheduler) decide is the most important use for that resource.
There are no guarantees that the interrupted task will ever regain
the CPU. Nor any notification that it has *lost* the CPU!
Yet, this is something we are comfortable with...
>> Everything in my system is message based ... Signals
>> are even delivered in this way
>
> OK, the usual sense of signals that I thought was reflected in your code
> sample, is basically delivering a simulated hardware interrupt to a
> running task, so it needs locks, critical sections and all that messy
> stuff.
Yes, the signal *is* delivered as a simulated hardware interrupt
(targeted towards that task). But, it is passed to the "task"
as a message from <whatever> task (the one who raises the signal)
*through* the kernel and to the scheduler as it (eventually) prepares
to resume that signalled task. (I.e., I need to be able to raise
a signal on one physical processor and have the task that it affects
reside on *another* physical processor).
>> Yes. Everything has the weight of a system call, effectively.
>
> In the case of your lawn sprinkler application I think that is fine.
> IMHO in this day and age, it's only worth dealing with low-level
> approaches if you're doing hard-real-time or have to run on 10-cent
> processors or something like that.
I chose the irrigation example because it avoids the issues of
timescale. So, we're not distracted by the efficiency of the
delivery mechanism, etc.
But, just because its "slow" and "computationally simple" (compared
to rendering video), that doesn't make it any less of a concern.
E.g., if there is only a few KIPs of spare capacity in the processor
(since processors do more than just control water valves), then
this can be just as constrained as trying to implement a mouse in
200 bytes of FLASH...
>> Well, the "resource" in question has already been passed along
>> to someone else.
>
> Yeah, the way I'm imagining, I wouldn't do it that way, as described
> above.
>
>> So, its more a question of do you let the task continue to consume
>> *other* resources in the mistaken belief that it still owns the
>> significant resource?
>
> In this case I'd say just kill the task, so it can restart in a
> completely known state. Admittedly I am somewhat under the influence of
> Erlang right now, and this is a core tenet of Erlang philosophy.
I had a friend who coded like that. Spawn hundreds of processes...
then, kill of the ones he decided weren;t important. :-/
>> Yes, but this approach assumes there are no associated activities
>> that must be unwound. I.e., that everything the task has done
>> can be discarded and recreated.
>
> The task would periodically post updates saying how far it has gotten
> (how much water has been dispensed, or whatever). When it's killed and
> restarts, it can take up where it left off.
Yes. All of these approaches are just juggling "responsibilities".
E.g., in my case, a task only checkpoint when it knows the resource
has been revoked *and* the nature of the task requires remembering
state (vs. simply restarting from scratch). If you require the
task to *periodically* checkpoint itself, then it has to come to
some sort of balance between spending all of its time checkpointing
(so it has very fine-grained resumption capability) vs. very little
checkpointing (so it doesn't waste its time keeping track of where
it was).
[Recall, the checkpointing must be done in a medium that is more
persistent than the task's context -- since the task's execution
environment can be torn down (completely) at any time. So, now
the system must provide a service for this -- and, one that is
sufficiently lightweight that invoking it OFTEN doesn't affect
performance... or, the performance of other tasks.]
(remember, you don't necessarily have a big disk sitting there
or scads of RAM... how much is a task granted access to? What
if it requires *more* to preserve its "significant" state?)
>> Imagine if the task is machining a piece of metal and the resource
>> that it wanted has been withdrawn.
>
> I don't understand this example--what would the "resource" be? In
Maybe a cutting tool. Maybe a power source because the next operation
puts significant demands on the available power supply (which is
shared by other machines in the facility). Maybe a coolant system
(what happens if you withdraw the coolant before it has had a
chance to achieve its intended goal... is the "piece" ruined?)
The point is, you may not be able to "resume" the operation.
You've just made an expensive piece of "scrap". And, even if
this is unavoidable, you have to *know* that it is scrap and
must be disposed of... not "resumed".
> general terms I'd say kill the process and let the crash handler park
> the tool in a safe position. But in this machining example, I'm
> imagining some kind of low level PID loop that would keep checking a
> flag to know if it had to bail out. In either case, the idea is to get
> to a place where you can restart later.
>
>> The "advantage" to an asynchronous notification *like* a signal is
>> it gives the developer as much rope as he wants
>
> The only reason for such "rope" is to push the limits of the hardware
> because more modular approaches are too slow or whatever. Computers are
> ridiculously powerful these days, so unless you're doing something
> extremely demanding (basically something that would have been impossible
> or economically unfeasible 10 years ago), seeking "rope" is probably a
> sign of doing something wrong.
Dealing with consumer markets, *everything* is economically unfeasible!
(unless you are catering to consumers who are not cost conscious).
E.g., I would imagine most irrigation controllers are implemented
with little PICs -- because their approach to the problem is much
more naive: turn the water on for X minutes, then advance to the
next zone. They don't look at the *needs* of their "consumers"
(plants/landscape). Nor do they worry about the availability of the
resource they are using. I.e., only a single zone is active at a time
(often, though not necessarily) and they assume someone else has
ensured an adequate supply *to* the valve manifold.
Here, for example, if I turned on all of the irrigation valves
simultaneously, several things would happen:
- household water pressure would drop noticeably
- the implied flow rates of each irrigation "emitter" would not
be correct (because the water pressure in the irrigation
system would have fallen below nominal)
- some of the irrigation loads probably wouldn't "work" at all
(i.e., not having enough static head to meet the required rise)
But, no particular "zone" should have to worry about this. It's
a system constraint. One that should be enforced by whatever
doles out the "water resource". If someone decides to "run a bath",
the individual irrigation zones shouldn't need to know that their
water use will interfere with that activity. (OTOH, something
"higher" in the system design should be able to enforce that
policy on the irrigation system)
>> The problem lies in the nature of asynchronous events and how
>> we think of them as developers.
>
> Right, they are messy and it's preferable to avoid them. E.g. by using
> message passing instead of signals.
But messages only "exist" when they are being examined. If, for
example, you issue a query to the database, you either assume the
query happens "fast enough" (whatever that means in your application)
*or* spawn a separate thread to process that query so you can
keep watching for messages. You now have yet another synchronization
issue to contend with, etc.
>> The other half of this is that it is REALLY HARD to test for these
>> things. You can't just inject an asynchronous event at every possible
>> place where it could occur and verify proper operation. :(
>
> You should probably look into model-checking tools if you absolutely
> have to pursue this approach. Dawson Engler's papers on using such
> tools to find crash bugs in Unix file systems might be of interest.
>
> Actually Tom Hawkins' "ImProve" program might be of some use to check
> that you got all your watering stuff right, in terms of turning correct
> combinations of valves on and off etc., if you're interested in
I've avoided the "combinations" issue entirely (at least in the
"zone controller tasks"). An individual zone deals only with the
needs of its "consumers" (plants). It knows that it may not have
access to the resources that it requires at all times (water,
"information", etc.) So, it knows how to deal with these deficits
on its own.
Similarly, the "water controller" only has to worry about the needs
of *its* consumers (several of which are the individual irrigation
zone controllers). And, how it can recover from those cases where
it can not supply the needs of those consumers (loss of water
supply, master valve failure, etc.)
> experimenting with high-tech approaches. I haven't used it but have
> been interested in it for a while:
>
> https://github.com/tomahawkins/improve/wiki/ImProve
>
> I did play around with Atom (a hard realtime DSL written by the same
> guy) and I think the approach is pretty powerful.
>
>> I really dislike telling people they "can't run with scissors" --
>> since those folks who are adept at doing so shouldn't be penalized by
>> the "clumsiness" of those who can't!
>
> Even someone capable of running with scissors without stabbing himself
> every time shouldn't do it outside of some dire emergency.
It boils down to what you consider an "emergency". And, how much
"spare capacity" you have available. E.g., if you can afford to
*walk* from place to place with those scissors, then there is
no need to take on the risk of running!
OTOH, if you don't have the luxury of being able to take a leisurely
stroll with them, then you either *break* (fail to meet your goals)
or you learn to run, safely!
> In this watering application you have (presumably) rather loose timing
> constraints, and roughly unlimited CPU resources. So I think you can do
> fine using safe, simple methods instead of running with scissors.
Again, irrigation is a trivial example. Imagine, instead, the
resources are physical processors and you are rendering video
in real time for distribution over the network. If one of those
resources becomes unavailable (crashes or is repurposed to put out
something more important than watching TV), how much spare
capacity do you design into the system so you can *leisurely*
go about recovering? (Remember, if the next frame isn't there
in a few tens of milliseconds, the user will perceive a visual
artifact in the rendered image!)
I.e., I would like to find *one* way of dealing with this sort
of thing instead of one way for "fast" things and another for
"slow" things, etc. (because that leaves "fast" and "slow" up
to debate and requires developers to appreciate the differences)
--don
[toc] | [prev] | [next] | [standalone]
| From | Paul Rubin <no.email@nospam.invalid> |
|---|---|
| Date | 2013-07-26 02:48 -0700 |
| Message-ID | <7xfvv1k5yh.fsf@ruckus.brouhaha.com> |
| In reply to | #182 |
Don Y <this@isnotme.com> writes:
> Actually, the irrigation program "computes" a fair amount, [snip]
That all seems like a trivial amount of computation.
> Along the way, it may have to escalate its request as the *hard*
> deadline approaches. ("Hey, if you don't let me water these things
> soon, they will die
Hard deadlines in realtime programming usually mean microseconds or so.
This plant watering stuff isn't even soft realtime (where you generally
want responses within milliseconds but are allowed to miss
occasionally).
> The question becomes one of whether you inform the process *before*
> you take action (or, even let the process itself "relinquish" the
> resource) or, if you inform the process after-the-fact. (or, if you
> just kill the process and don't even worry about informing it! :> )
Sounds like you might want a two-step approach: 1) ask the process to
give the resource back; 2) if that doesn't work within a reasonable
timeout, kill the process. I'd really stay away from this notion of
reassigning the resource while the process is trying to use it and
doesn't know what has happened.
> or intentionally delays relinquishing it (like a youngster trying
> to postpone bed-time), then other consumers suffer.
If you have hostile applications in your system, you have a completely
different design problem. In a normal system, just have a few safety
timeouts and kill processes that miss them.
> I've taken the other approach. A process owns (permanently?) the
> resources. It then doles them out, on request, to other consumers.
That is fine.
> When it wants/needs to give the resource to another consumer, it does
> so -- and notifies the previous owner that it has LOST the resource.
I think I'd use an extra protocol step so that the process can give back
the resource gracefully. If you've already decided you want to do
something different (and in my opinion more error-prone), I don't
understand why you're asking for advice.
> We don't notify a task that we are going to take the *CPU* away
That is different. Tasks that get preempted in normal OS's usually
don't even know that anything has happened.
> But, just because its "slow" and "computationally simple" (compared
> to rendering video), that doesn't make it any less of a concern.
> E.g., if there is only a few KIPs of spare capacity in the processor
> (since processors do more than just control water valves),
I don't think they even make processors slow enough for a few KIPs to
matter for something like this.
>>Erlang philosophy.
> I had a friend who coded like that. Spawn hundreds of processes...
> then, kill of the ones he decided weren;t important. :-/
Processes in Erlang are very cheap, and having 1000's of them is no big
deal. On other systems they may cost more.
> (remember, you don't necessarily have a big disk sitting there
> or scads of RAM... how much is a task granted access to?
IIRC one of the first questions I asked you was what OS you were using,
what language, etc. I've run Python on boards with as little as 64 meg
of ram and Erlang's requirements are comparable. Of course 64MB was a
lot of memory not that long ago, and I tossed out that number casually
just to make you jump ;-).
>>> Imagine if the task is machining a piece of metal
> The point is, you may not be able to "resume" the operation.
If you can't, then you can't. The best you can do is to try to plan the
operation to be resumable, if you think you might have to preempt it.
> Dealing with consumer markets, *everything* is economically
> unfeasible! ... E.g., I would imagine most irrigation controllers are
> implemented with little PICs
You were the guy trying to make patch panels on laser printers and buy
solenoid valves from Wal-mart or something? I don't think you're in a
consumer market making millions of devices. In your situation for a
one-off thing I'd use something like a Beagleboard. If you're making
millions of devices and have to squeeze pennies out of the hardware
cost, you do that by spending far more up front on software development.
But, even then, message passing is a reasonable approach. Traditional
Forth multitaskers use a few hundred bytes and are bloody fast and can
run fine on a Cortex M0 or equivalent. If you're using some simple C
RTOS then it's probably comparable.
> But messages only "exist" when they are being examined. ... you either
> assume the query happens "fast enough"
Yes, in a hard realtime system you can't necessarily use that approach
and you may end up havint to resort to something much more difficult.
In soft realtime with these relaxed requirements, you can use simpler
methods without much trouble.
> I.e., I would like to find *one* way of dealing with this sort
> of thing instead of one way for "fast" things and another for
> "slow" things, etc.
Just like in everyday life, dealing with "slow" things is often (at
least up front) much cheaper and less hassle than "fast" things.
Consider mailing an envelope somewhere vs. paying Federal Express for
same day delivery. Or using an off-the-shelf CPU board instead of
making an ASIC. One of the consequences of cheap powerful SBC's
(Raspberry Pi etc) is that you can use relatively resource hungry
programming approaches to drastically shorten development effort (and
therefore decrease cost), even for relatively low-budget embedded
projects. You are freed from a lot of constraints.
It's completely sensible for the most economical programming techniques
to be different than what you'd do in a resource constrained system,
just as those techniques are different again than what you'd do in
hardware (or Verilog). Obviously you can use constrained methods on big
processors, so that lets you use the same approach everywhere, but it
means you do a lot of unnecessary work.
[toc] | [prev] | [next] | [standalone]
| From | Don Y <this@isnotme.com> |
|---|---|
| Date | 2013-07-26 04:19 -0700 |
| Message-ID | <kstm05$qn5$1@speranza.aioe.org> |
| In reply to | #183 |
Hi Paul,
On 7/26/2013 2:48 AM, Paul Rubin wrote:
> Don Y <this@isnotme.com> writes:
>> Actually, the irrigation program "computes" a fair amount, [snip]
> That all seems like a trivial amount of computation.
In terms of "number crunching", it's trivial. A four function
calculator would suffice.
But, in terms of processor cycles, there's a lot more than meets
the eye. E.g., querying the database requires issuing the RPC
for the actual "SELECT", concurrently setting a timer to ensure
the task doesn't "wait too long" for the reply; then, parsing
the reply to examine each emitter, it's flow rate, the permeability
of the soil around it so you know what the water *previously*
dispensed there has "done" in the time since it was dispensed;
how much the plant's root systems will have taken up, how stressed
*that* plant has been (wind/sun) in the days (?) since it was last
watered so you understand *its* needs (and how close its effective
HARD deadline is); meanwhile, querying any other emitters (possibly
serviced by other zones) that have added to the moisture content
in that area; then, looking at all of the plants and making a decision
as to how critical the provision of water from *this* zone is at
this time -- along with how large a "dose".
[BTW, this is what industrial commercial systems do to varying degrees]
[Remember, conditions are *always* changing. You can't just make
a decision and sit on it until you think it is time to act on it
(which is what a naive controller does)]
Just moving messages (RPC's) up and down through the network stack
consumes more resources than a "conventional" irrigation controller
would in a *week*!
By contrast, a PIC-based controller does:
while (FOREVER) {
sleep(water_interval - water_time) // typically days!
valve(X, ON);
sleep(water_time) // typically minutes
valve(X, OFF);
}
>> Along the way, it may have to escalate its request as the *hard*
>> deadline approaches. ("Hey, if you don't let me water these things
>> soon, they will die
>
> Hard deadlines in realtime programming usually mean microseconds or so.
> This plant watering stuff isn't even soft realtime (where you generally
> want responses within milliseconds but are allowed to miss
> occasionally).
No. This is a common misconception.
"Hard" and "soft" have ABSOLUTELY NO BEARING ON THE MAGNITUDE OF THE
TIMES INVOLVED!
Rather, they are concerned with the shape of the value function
associated with the deadline. HRT problems have a value function
that "goes to zero" at the deadline. I.e., missing a HRT deadline
means you might as well reset the processor and start working on
something else -- there is no value left to continued work (i.e.,
expenditure of resource) towards the goal.
[NON-realtime problems have no "deadlines"]
By contrast, an SRT problem has a value function that decreases
at and after the deadline. I.e., there is more value to getting
it done BEFORE the deadline -- though there may still be value
to getting it done *after* the deadline has passed! (Of course,
most SRT problems are encapsulated within a "final", HARD deadline
beyond which their value is inconsequential).
[Note a *system* can contain hard and soft real-time problems.]
How far in the future a deadline is -- or, how *often* it is -- has
no bearing on the HARD vs. SOFT distinction. Sending a probe to
Pluto could have a deadline *years* in the future. Does that make
it "soft"? Even an *abacus* onboard the spacecraft could process
innumerable "instructions" in that time period! But, when it comes
time for a maneuvering thruster to be engaged, it had *better* be
engaged (else the spacecraft misses its orbital insertion, etc.)
Similarly, events from a mouse "wheel" can come at tens of Hz.
Yet, if you miss 80% of them *completely*... <shrug>. Or, if you
handle them *late*, it could still be acceptable.
If you don't dispense water for the plants in a given zone *exactly*
when you would like to, it's not the end of the world. For whatever
reason (too busy computing pi? water resource not yet available?),
a SOFT deadline is missed. But, there is still value to supplying
water -- whether that's a few minutes later or a few hours! (i.e.,
the shape of the value function depends on the needs of the particular
plants being serviced, their recent watering history, environmental
factors and the value of the plants themselves! It's relatively
easy to regrow wildflowers; considerably harder to regrow a fruit
tree -- or ensure it doesn't shed it's blossoms and, thus, lose
an entire crop of fruit for this growing season!)
OTOH, there comes a point where you've simply waited too long and
any attempt at watering is going to yield no results (or, even
NEGATIVE results!). This is the HARD deadline that represents
sink or swim -- beyond which it is silly to even compute how
late you are!
If the cacti in the side yard don't get watered at 5PM today, they
won't mind if it happens 5PM a *week* from today! OTOH, if the rose
bushes aren't watered 8twice* a day, they are toast! (unless, of
course, it is winter time in which case they should be watered
very INfrequently lest the roots rot!)
>> The question becomes one of whether you inform the process *before*
>> you take action (or, even let the process itself "relinquish" the
>> resource) or, if you inform the process after-the-fact. (or, if you
>> just kill the process and don't even worry about informing it! :> )
>
> Sounds like you might want a two-step approach: 1) ask the process to
> give the resource back; 2) if that doesn't work within a reasonable
> timeout, kill the process. I'd really stay away from this notion of
> reassigning the resource while the process is trying to use it and
> doesn't know what has happened.
Again, how a process is coded can vary with the consequences of
that implementation. I.e., deliver a signal and the process
can be prevented from doing *anything* in the absence of the
revoked resource. The signal can even cause a "message" to
be delivered to the task saying "please release the resource, NOW!".
On the other hand, if you rely on "cooperation", then you have
to qualify this cooperation as well as quantify it. I.e., when
requested, you *must* relinquish the resource within time T.
Even if your task has insufficient priority to claim use of
the CPU in that period!
>> or intentionally delays relinquishing it (like a youngster trying
>> to postpone bed-time), then other consumers suffer.
>
> If you have hostile applications in your system, you have a completely
> different design problem. In a normal system, just have a few safety
> timeouts and kill processes that miss them.
Many systems have to tolerate potentially hostile processes.
Esp if they are designed to be "open". What's to prevent an
"app" in your smartphone from taking a resource and holding onto it
indefinitely? Or, an application on your PC? What do you
do in the absence of a human presence to intervene and "kill"
the offending task? What do other tasks do *while* this
condition persists?
(What do you do when there is no "human" available to kick your
system back into operation?)
>> I've taken the other approach. A process owns (permanently?) the
>> resources. It then doles them out, on request, to other consumers.
>
> That is fine.
>
>> When it wants/needs to give the resource to another consumer, it does
>> so -- and notifies the previous owner that it has LOST the resource.
>
> I think I'd use an extra protocol step so that the process can give back
> the resource gracefully. If you've already decided you want to do
> something different (and in my opinion more error-prone), I don't
> understand why you're asking for advice.
I was actually hoping for a mechanism that more intuitively
allowed the developer to *see* this "event" without the explicit
coding that, e.g., signals require.
E.g., if you are talking of a single resource (within an app),
then:
handle = await_resource(resource_sought)
spawn(use_resource)
result = await_release(handle)
if (result == I_released_it_when_I_was_finished)
// success
else
// use_resource was not able to complete as expected
is a more robust coding style. Something that can easily be
applied boilerplate style. Get what you need. Hve something
do the work while you wait for it to "finish". Then, verify
that it's "finishing" was truly the result of the task
completing as expected vs. something else causing it to terminate.
However, it falls down (gets ugly) when "use_resource" must
then request some *other* resource, etc.
>> We don't notify a task that we are going to take the *CPU* away
>
> That is different. Tasks that get preempted in normal OS's usually
> don't even know that anything has happened.
How's that different from pulling a resource out from under the
eyes of a task? The task doesn't know anything has happened. Or,
I could conceivably block the task until I was able to restore
the resource to it!
I.e., we treat "CPU time" as a *different* sort of resource...
And, don't seem to have any problem with that.
Simmilarly, we treat physical memory as a different resource
(in a VM system) than "logical" memory. We ignore the fact that
accessing location X might be nearly instantaneous while X+1 may
take milliseconds to access (if the page containing it's backing
store has to be swapped in)
>> But, just because its "slow" and "computationally simple" (compared
>> to rendering video), that doesn't make it any less of a concern.
>> E.g., if there is only a few KIPs of spare capacity in the processor
>> (since processors do more than just control water valves),
>
> I don't think they even make processors slow enough for a few KIPs to
> matter for something like this.
You are assuming the processor is *only* working on this task.
Or, are accustomer to applications/systems where the system idle
loop *always* gets a chance to run (i.e., when the processor is
never overloaded)
>>> Erlang philosophy.
>> I had a friend who coded like that. Spawn hundreds of processes...
>> then, kill of the ones he decided weren;t important. :-/
>
> Processes in Erlang are very cheap, and having 1000's of them is no big
> deal. On other systems they may cost more.
Yup. In my friend's case, a task (process an inappropriate term)
was a handful of bytes! Hence my caution in using terms like
threads, processes, tasks, etc. I've deployed systems where an
"execution unit" was as small as a couple of bytes and as large
as many megabytes. So, what's "normal"?
But, "cheap" is a relative term. 1000's of processes on a machine
with limited resources can be impossible. I.e., C.A.E doesn't
presume you're running on a desktop, etc. How many tasks are
running inside your mouse? :-/
>> (remember, you don't necessarily have a big disk sitting there
>> or scads of RAM... how much is a task granted access to?
>
> IIRC one of the first questions I asked you was what OS you were using,
> what language, etc. I've run Python on boards with as little as 64 meg
> of ram and Erlang's requirements are comparable. Of course 64MB was a
> lot of memory not that long ago, and I tossed out that number casually
> just to make you jump ;-).
Scale that back by an order of magnitude or two! :> Think
"SoC" not "SBC". Think "several dollars" vs. "dozens of dollars".
And, think scores of machines and not singletons.
>>>> Imagine if the task is machining a piece of metal
>> The point is, you may not be able to "resume" the operation.
>
> If you can't, then you can't. The best you can do is to try to plan the
> operation to be resumable, if you think you might have to preempt it.
>
>> Dealing with consumer markets, *everything* is economically
>> unfeasible! ... E.g., I would imagine most irrigation controllers are
>> implemented with little PICs
>
> You were the guy trying to make patch panels on laser printers and buy
> solenoid valves from Wal-mart or something? I don't think you're in a
> consumer market making millions of devices.
Why do you assume that because I want to have a way for folks
with shallow pockets to ALSO take advantage of a technology
that these are the *only* people who will take advantage of that
technology?
Why do people build MythTV boxes? Don't their cable providers
offer DVR's? Surely, it's got to be cheaper to buy/rent a DVR
THAT YOU KNOW WILL WORK than to tinker with trying to get
some bits of code to work on a machine you've thrown together
from scraps! Even assuming your time is "free", you prsumably
would want the resulting device to *work*, reliably! ("Dang!
My MythTV box didn't record the programs I wanted. I guess
my time server was screwed up and it didn't know that today
was Friday...")
Similarly, should video recording technology ONLY be available to
people who want to hack it together from odds and ends? So, if
you aren't technically literate (and motivated!), you can't
take advantage of that technology? Regardless of how deep your
pockets are?
Rather, wouldn't you want a solution that folks with money (and
no time, inclination, etc.) could purchase (subsidize!) while
also providing a means by which folks with more *time* (and
technical expertise) than money (or, perhaps, more *desire*)
can also avail themselves of that technology?
[Well, I have no idea what you would want. But, *I* would
want a solution that can be approached from each of these
perspectives]
E.g., I designed my network speakers so you could implement them
with a bunch of surplus PC's -- one for the server and one for
each speaker/speaker-pair. (assuming you have the space for
a whole PC where you would want one!)
Or, you could buy a bare board and components and assemble one
for yourself -- possibly housing it in a tin can in lieu of a
"real" enclosure!
Or, you could purchase one commercially -- for considerably more
(as there are people wanting to make a profit in that distribution
chain!).
> In your situation for a
> one-off thing I'd use something like a Beagleboard. If you're making
> millions of devices and have to squeeze pennies out of the hardware
> cost, you do that by spending far more up front on software development.
Exactly. You don't write your app in Python. You don't expect it
to have GB of RAM available and GIPs of CPU. And, you don't create
an environment for others to augment/maintain the design that will
lead to the system, as a whole, being flakey.
> But, even then, message passing is a reasonable approach. Traditional
> Forth multitaskers use a few hundred bytes and are bloody fast and can
> run fine on a Cortex M0 or equivalent. If you're using some simple C
> RTOS then it's probably comparable.
>
>> But messages only "exist" when they are being examined. ... you either
>> assume the query happens "fast enough"
>
> Yes, in a hard realtime system you can't necessarily use that approach
> and you may end up havint to resort to something much more difficult.
> In soft realtime with these relaxed requirements, you can use simpler
> methods without much trouble.
Again, hard and soft have nothing to do with how *fast* something
is. I.e., how many instruction cycles it will take to execute.
So, how many cycles something takes has nothing to do with the
soft/hard-ness of the RT. Those things only affect the amount
of *resources* available to the application.
>> I.e., I would like to find *one* way of dealing with this sort
>> of thing instead of one way for "fast" things and another for
>> "slow" things, etc.
>
> Just like in everyday life, dealing with "slow" things is often (at
> least up front) much cheaper and less hassle than "fast" things.
> Consider mailing an envelope somewhere vs. paying Federal Express for
> same day delivery. Or using an off-the-shelf CPU board instead of
> making an ASIC. One of the consequences of cheap powerful SBC's
> (Raspberry Pi etc) is that you can use relatively resource hungry
> programming approaches to drastically shorten development effort (and
> therefore decrease cost), even for relatively low-budget embedded
> projects. You are freed from a lot of constraints.
This is fine if *all* you are doing is soft (or fast). And, if
your "solution" doesn't have to change from one domain to the other
as it evolves (since folks are hesitant to reengineer an entire
application -- prefering, instead, to try to tweak it to death).
E.g., when I originally coded the irrigation controller (different
system), it mimicked the "naive" controllers (electromechanical)
that I had experience with at the time (growing up, no one "watered"
the yard; The Rain did that!). Then, I replaced the sequential
zone N then zone N+1 approach with a system that allowed multiple
zones to be watered concurrently. This required coordination
to ensure "too many" zones didn't try to operate simultaneously.
Now, I want to give it more smarts *and* reflect the impact it
can have on other "water consumers" here. And, since I can't
predict what those uses will be [actually, this is a small lie],
I need to be able to abort a watering cycle and resume it at
some later time.
[The same sort of algorithm can also be applied to controlling
access to other shared resources -- electricity, natural gas,
etc. Don't let the air conditioner compressor kick in when
you are baking -- especially if you are on a ToU tarrif!]
> It's completely sensible for the most economical programming techniques
> to be different than what you'd do in a resource constrained system,
> just as those techniques are different again than what you'd do in
> hardware (or Verilog). Obviously you can use constrained methods on big
> processors, so that lets you use the same approach everywhere, but it
> means you do a lot of unnecessary work.
I "spend resources" on making products/environments more robust
and/or useable. E.g., protected memory domains so task A can't
screw with task B's resources (this costs resources which translates
to real money when you have to buy chip A vs chip B). RTOS's
vs. MTOS's (because MTOS's don't/can't make timeliness guarantees
even if they can be implemented more simply/cheaply). "Services"
instead of "libraries" (because services can be more universally
applied and controlled).
I.e., the goal is to use "big system" capabilities on "tiny iron".
So you afford the developer with the environment most conducive
to him producing a benevolent/harmless application without incurring
all the cost of twiddling individual bits.
To that end, being able to provide a "template" that guides how
you can craft a "robust" application -- and, what you can expect
*from* the system via that template -- can make these goals much
more attainable.
"Invoke this service in this manner; expect these results."
"Request a resource using this mechanism; expect to handle
these situations/exceptions."
etc. But, at the same time, protecting the *system* from the
developer's greed/folly!
--don
[toc] | [prev] | [next] | [standalone]
| From | Paul Rubin <no.email@nospam.invalid> |
|---|---|
| Date | 2013-07-26 09:46 -0700 |
| Message-ID | <7x1u6lclqg.fsf@ruckus.brouhaha.com> |
| In reply to | #184 |
Don Y <this@isnotme.com> writes: > the eye. E.g., querying the database requires issuing the RPC > for the actual "SELECT", concurrently setting a timer to ensure I didn't realize there was an SQL database in this, but if there is, the computer is big enough that it's all still trivial. > I.e., the goal is to use "big system" capabilities on "tiny iron". These same methods work fine in relatively small systems (say a few KB of ram) if you don't mind using low level languages like C or Forth and carefully allocating memory by hand, not having memory protection, etc (see the Mars Rover article). In the smallest 8-bit cpu's or in hardware, you may have less flexibility.
[toc] | [prev] | [next] | [standalone]
| From | Don Y <this@isnotme.com> |
|---|---|
| Date | 2013-07-26 10:21 -0700 |
| Message-ID | <ksub5t$o1d$1@speranza.aioe.org> |
| In reply to | #185 |
Hi Paul, On 7/26/2013 9:46 AM, Paul Rubin wrote: > Don Y <this@isnotme.com> writes: >> the eye. E.g., querying the database requires issuing the RPC >> for the actual "SELECT", concurrently setting a timer to ensure > > I didn't realize there was an SQL database in this, but if there > is, the computer is big enough that it's all still trivial. No, the RDBMS is in *another* machine (note I said "RPC" and not "IPC" ) elsewhere on the network. This (and others) is just a *client*. As long as you have the resources for the protocol stack, "software" to issue the query and catch/parse the result, you can implement such a client on things as tiny as a PIC (and smaller). You just can't *do* much in terms of issuing lots of requests per unit time. Nor *accumulating* many results! But, if you are clever/methodical about it, you can handle a virtually unlimited number of emitters, "plants", etc. and come up with *a* number that indicates how much water you should dispense "now". Again, "SoC" not "SBC" (i.e., think: fraction of an MB of FLASH and tens of KB of RAM -- but nothing beyond that!). A "single chip" solution (plus I/O's). >> I.e., the goal is to use "big system" capabilities on "tiny iron". > > These same methods work fine in relatively small systems (say a few KB > of ram) if you don't mind using low level languages like C or Forth and > carefully allocating memory by hand, not having memory protection, etc > (see the Mars Rover article). In the smallest 8-bit cpu's or in > hardware, you may have less flexibility. You don't have to allocate memory by hand -- nor statically (another common misconception). Nor do you have to live without memory protection (though you probably live without backing store unless you *add* secondary storage to the device). There are lots of SoC's nowadays that can give you a full-featured environment without the *quantity* of resources you might have in a desktop, etc. Even with 8 bitters you can give the developer the "feel" of a big machine. E.g., I had a Z180-based system (essentially 8 bits with a 1MB address space) where you would be hard pressed to know you *weren't* writing UN*X code! (aside from the dreadful slowness of a ~6MHz, 25+ year-old, 8 bit machine!) --don --don
[toc] | [prev] | [next] | [standalone]
| From | Hans-Bernhard Bröker <HBBroeker@t-online.de> |
|---|---|
| Date | 2013-07-26 19:25 +0200 |
| Message-ID | <b5fpouFs6qcU1@mid.dfncis.de> |
| In reply to | #183 |
On 26.07.2013 11:48, Paul Rubin wrote: > Don Y <this@isnotme.com> writes: > Hard deadlines in realtime programming usually mean microseconds or so. > This plant watering stuff isn't even soft realtime (where you generally > want responses within milliseconds but are allowed to miss > occasionally). This is a very common misconception, but still just as wrong. Realtime has nothing to do whatsoever with the length of any particular interval of time. It doesn't matter if your deadline is coming every 50 nanoseconds or once a year. If there's a deadline, and it's defined as a point fixed in time, then you're doing realtime processing. Nor is the distinction between soft and hard realtime to be found in the timescales involved, but in the gravity of consequences if you miss a deadline. In other words, realtime is about whether there _is_ a "too late", not _when_ that might be.
[toc] | [prev] | [next] | [standalone]
| From | Paul Rubin <no.email@nospam.invalid> |
|---|---|
| Date | 2013-07-26 10:51 -0700 |
| Message-ID | <7xd2q5b46d.fsf@ruckus.brouhaha.com> |
| In reply to | #187 |
Hans-Bernhard Bröker <HBBroeker@t-online.de> writes: > Realtime has nothing to do whatsoever with the length of any > particular interval of time. It doesn't matter if your deadline is > coming every 50 nanoseconds or once a year. Pedantically you and Don are correct. In practice in terms of software technique, the interval lengths actually matter.
[toc] | [prev] | [next] | [standalone]
| From | Roberto Waltman <usenet@rwaltman.com> |
|---|---|
| Date | 2013-07-26 17:06 -0400 |
| Subject | Does the Buddha have a real time nature? ;) (was Resource revocation) |
| Message-ID | <b8o5v85soicm3i7fd52ktuq014lgqcmuja@4ax.com> |
| In reply to | #188 |
Hans-Bernhard Bröker wrote: >... >In other words, realtime is about whether there _is_ a "too late", not >_when_ that might be. Don Y wrote: >... >Real-time == deadline. Period. I am always puzzled by those "definitions" (for lack of a better term) that seem to ignore the obvious: Real time is about windows/time slots in which an action is effective. i.e., too early is as bad as too late. For a few trivial examples: In a package sorting installation, the diverter that pushes out a box from a conveyor belt must operate when the box is in front of it, not after, not before. Firing a rocket to slow down a space craft for reentry must happen at the proper time, not "before" a certain time. Pushing down the cork in an automated bottling facility works best when the bottle is below it. And so on... -- Roberto Waltman [ Please reply to the group, return address is invalid ]
[toc] | [prev] | [next] | [standalone]
| From | Don Y <this@isnotme.com> |
|---|---|
| Date | 2013-07-26 17:12 -0700 |
| Subject | Re: Does the Buddha have a real time nature? ;) (was Resource revocation) |
| Message-ID | <ksv399$m2k$1@speranza.aioe.org> |
| In reply to | #190 |
Hi Roberto, On 7/26/2013 2:06 PM, Roberto Waltman wrote: > Hans-Bernhard Bröker wrote: >> ... >> In other words, realtime is about whether there _is_ a "too late", not >> _when_ that might be. > > Don Y wrote: >> ... >> Real-time == deadline. Period. > > I am always puzzled by those "definitions" (for lack of a better term) > that seem to ignore the obvious: Real time is about windows/time slots > in which an action is effective. i.e., too early is as bad as too > late. There is a bit of slight of hand, here. A task can not complete before it has begun (<grin>). So, if you alter the release time of the task (the time at which it becomes *available* to execute), you can shift the earliest completion point for the task. I.e., the start of your "window". Then, the deadline becomes the *end* of the window. Typically, when you are encountering these sorts of applications, you design so that you have the "answer", reliably, some time "around" the start of the window and then defer its effectivity until after the formal start of the window. The delaying action ensures the result is never *applied* before the window start while the deadline delimits the definition of "too late". We do this in hardware designs, too. Set-up signals and propagate them into their intended circuits "at the next clock edge", etc. > For a few trivial examples: > > In a package sorting installation, the diverter that pushes out a box > from a conveyor belt must operate when the box is in front of it, not > after, not before. > > Firing a rocket to slow down a space craft for reentry must happen at > the proper time, not "before" a certain time. > > Pushing down the cork in an automated bottling facility works best > when the bottle is below it. > > And so on...
[toc] | [prev] | [next] | [standalone]
| From | Tom Gardner <spamjunk@blueyonder.co.uk> |
|---|---|
| Date | 2013-07-27 09:45 +0100 |
| Subject | Re: Does the Buddha have a real time nature? ;) (was Resource revocation) |
| Message-ID | <VMLIt.29752$i03.914@fx03.am4> |
| In reply to | #191 |
On 27/07/13 01:12, Don Y wrote:> There is a bit of slight of hand, here. A task can not complete > before it has begun (<grin>). That isn't necessarily as clear as you might believe. If you check an English/Hindi dictionary you will find that the word for "yesterday" is the same as the word for "tomorrow" (कल pronounced "kal"). This is also deeply embedded (ho ho) in their culture, which doesn't have an "arrow of time" but does have a "wheel of time".
[toc] | [prev] | [next] | [standalone]
| From | Don Y <this@isnotme.com> |
|---|---|
| Date | 2013-07-27 12:28 -0700 |
| Subject | Re: Does the Buddha have a real time nature? ;) (was Resource revocation) |
| Message-ID | <kt1702$neu$1@speranza.aioe.org> |
| In reply to | #192 |
Hi Tom, On 7/27/2013 1:45 AM, Tom Gardner wrote: > On 27/07/13 01:12, Don Y wrote:> There is a bit of slight of hand, > here. A task can not complete > > before it has begun (<grin>). > > That isn't necessarily as clear as you might believe. > If you check an English/Hindi dictionary you will find > that the word for "yesterday" is the same as the word > for "tomorrow" (कल pronounced "kal"). > > This is also deeply embedded (ho ho) in their culture, > which doesn't have an "arrow of time" but does have > a "wheel of time". Well, that makes the problem moot, then! Miss a deadline (window)? Just turn the crank and try again next time 'round!!!
[toc] | [prev] | [next] | [standalone]
| From | Hans-Bernhard Bröker <HBBroeker@t-online.de> |
|---|---|
| Date | 2013-07-27 14:11 +0200 |
| Subject | Re: Does the Buddha have a real time nature? ;) (was Resource revocation) |
| Message-ID | <b5hrn1FarkkU1@mid.dfncis.de> |
| In reply to | #190 |
On 26.07.2013 23:06, Roberto Waltman wrote: > I am always puzzled by those "definitions" (for lack of a better term) > that seem to ignore the obvious: Real time is about windows/time slots > in which an action is effective. i.e., too early is as bad as too > late. That's because time isn't as symmetric as you make it out to be. We can always delay delivering a result that we already have before it's needed, but there's no way we can deliver a result that we don't have yet. > In a package sorting installation, the diverter that pushes out a box > from a conveyor belt must operate when the box is in front of it, not > after, not before. Which makes the diverter operation synchronized, rather than realtime. The algorithm that figures out whether the diverter ought to be fired, on the other hand, is a realtime task. If that algorithm completes half an hour because that package comes by, that's no more than a minor nuisance. But if it runs a millisecond late, it has failed.
[toc] | [prev] | [next] | [standalone]
| From | Don Y <this@isnotme.com> |
|---|---|
| Date | 2013-07-26 12:00 -0700 |
| Message-ID | <ksugvu$8q5$1@speranza.aioe.org> |
| In reply to | #187 |
Hi Hans-Bernhard, On 7/26/2013 10:25 AM, Hans-Bernhard Bröker wrote: > On 26.07.2013 11:48, Paul Rubin wrote: >> Don Y <this@isnotme.com> writes: > > Nor is the distinction between soft and hard realtime to be found in the > timescales involved, but in the gravity of consequences if you miss a > deadline. I think "gravity" suggests "safety critical", "life support", etc. Rather, I view it as the *value* of a timely result. I.e. if your product picks bottles off a conveyor belt, then missing a deadline means a bottle crashes onto the floor. This might be relatively insignificant in terms of its financial value, etc. But, the effort expended trying to *get* the bottle before it crashed to the floor has been wasted. *And*, no further effort will change the outcome! (i.e., *drop* that task from your workload) > In other words, realtime is about whether there _is_ a "too late", not > _when_ that might be. This is an excellent way of putting it! --don
[toc] | [prev] | [next] | [standalone]
| From | stephenXXX@mpeforth.com (Stephen Pelc) |
|---|---|
| Date | 2013-07-27 16:49 +0000 |
| Message-ID | <51f3f9a3.1434256188@news.demon.co.uk> |
| In reply to | #187 |
On Fri, 26 Jul 2013 19:25:59 +0200, =?ISO-8859-1?Q?Hans-Bernhard_Br=F6ker?= <HBBroeker@t-online.de> wrote: >Nor is the distinction between soft and hard realtime to be found in the >timescales involved, but in the gravity of consequences if you miss a >deadline. Although the usual easy definition of hard real-time is: "Late answers are wrong answers" there are a few occasions when doing something too early is also wrong. Hard real-time is really about doing things at the right times. Stephen -- Stephen Pelc, stephenXXX@mpeforth.com MicroProcessor Engineering Ltd - More Real, Less Time 133 Hill Lane, Southampton SO15 5AF, England tel: +44 (0)23 8063 1441, fax: +44 (0)23 8033 9691 web: http://www.mpeforth.com - free VFX Forth downloads
[toc] | [prev] | [next] | [standalone]
Page 1 of 4 [1] 2 3 4 Next page →
Back to top | Article view | comp.realtime
csiph-web