Re: Why RosAsm Breaks on a large number of symbols
From: Beth (BethStone21_at_hotmail.NOSPICEDHAM.com)
Date: 07/12/04
- Next message: Phil Carmody: "Re: Why RosAsm Breaks on a large number of symbols"
- Previous message: J.Mo: "Re: ASM vs HLL : absurd war"
- In reply to: Randall Hyde: "Re: Why RosAsm Breaks on a large number of symbols"
- Next in thread: Phil Carmody: "Re: Why RosAsm Breaks on a large number of symbols"
- Reply: Phil Carmody: "Re: Why RosAsm Breaks on a large number of symbols"
- Reply: hutch--: "Re: Why RosAsm Breaks on a large number of symbols"
- Reply: The Wannabee: "Re: Why RosAsm Breaks on a large number of symbols"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Mon, 12 Jul 2004 07:02:33 GMT
Randy wrote:
> Beth wrote:
> > And _BLOCKING_ is a form of "asynchronous
notification"...and
> > "GetMessage" _blocks_...
>
> Whoops!
> Certainly you meant "blocking is a form of *synchronous
notification*", no?
Whoops, indeed...
Yes, that's what I meant...I've been driven around in circles by
all this terminological confusion ;)...
> > It is NOT "checking for the availability of data"...calling
> > "GetMessage" is effectively: "Right, I'm going to block
> > now...please _NOTIFY_ me when a message becomes
available"...
>
> Any message, not just the one you're polling for.
> Which means you have to waste time processing the message
> you weren't interested in, loop back, and block again.
Yes; Entirely correct...but then this is an "event driven"
system...the order of messages is mostly out of an application's
control...
This is the absurdity of this whole argument, really...when it's
_ANY_ message, you're NOT polling because all messages are
equally "relevent" when you have no particular message in
mind...when it's a _particular_ message you want then you're,
indeed, "polling for" that particular message...
The distinction I'm making to state that "a GetMessage message
loop is not polling" is that this message loop is NOT for any
one particular message...it's for _ANY_ and _ALL_ messages that
the application encounters...therefore, it's not a "polling
loop"...the _LOOP ITSELF_ does not "poll"...
But the perspective you're looking at the message loop from is a
_particular lone iteration_ of the loop, waiting for a
_particular_ message...other irrelevent messages may happen so
you discard or "default process" them and then loop back to
"GetMessage" again...therefore, you're "polling"...the
_ITERATION_ is "polling"...but the _LOOP_ overall is not...
Hence, the relative uselessness of the term "polling" in this
instance...it bizarrely is _AND_ isn't "polling", depending on
the perspective of the situation you're taking...I'm stickng by
"NOT polling" because the _LOOP ITSELF_ is for _ANY_ and _ALL_
messages so the _LOOP_ is not "polling"...a _particular
instance_ of a _particular iteration_ with regard to a
_particular message_, though, bizarrely _IS_ "polling"...
We have got an instance of that problem I was talking about with
the optical illusion image that's _BOTH_ a "young lady" _AND_ an
"old woman" at the very same time...which one you decide to call
it completely depends on how you're looking at the image...yes,
even though the image is exactly the same _physical_ thing
whatever your interpretation of it...we're looking at the same
lines and the same filled in spaces but concluding two _EQUALLY
VALID_ perspectives of the image...
It's arguably "polling" and "non-polling", depending on your
perspective...BUT, I would argue that as we are talking about
the _LOOP_ then, overall, that loop is concern with _any_ and
_all_ messages so, so to speak, "all messages are equal in the
eyes of GetMessage"...hence, why I'm siding with "not polling"
here...
> Your argument would be quite correct if Windows sent
> *only* the message that the application was waiting for.
What if the application is waiting for _ANY_ message?
And, indeed, when an application calls "GetMessage", isn't it
doing exactly that?
Now, as a programmer, you're really, really totally uninterested
by "WM_NULL" (which is only there, apparently, as a means for
Windows to test the "responsiveness"...it sends a WM_NULL as the
first message to an application simply to test that the
application is actually accepting messages and correctly passing
the "uninteresting" ones to "default processing" ;)...so, you
really don't care about this message, it's "uninteresting"...you
want to throw them out until you get to the juicy messages...
But this is not the perspective of the program and, therefore,
the loop itself...this loop deals with _any_ and _all_ messages
provided to it...you are NOT writing a "WM_PAINT" message loop
and a "WM_CREATE" message loop and a "WM_DESTROY" message loop
and so on and so forth...you're writing _ONE_ message loop that
deals with _any_ and _all_ messages ("interesting" _OR_
"uninteresting")...
When you call "GetMessage" (without supplying specific "filter"
parameters) then it _IS_ exactly waiting on _ANY_ message...even
if you're waiting only for "interesting" messages then if there
is _more than one_ such message (likely), then you can't only
wait on a "filter" but have to accept _any_ message and then
manually "filter" it (possibly in the message loop, possibly in
the "window procedure")...
A further confusion and distinction here is that, actually,
Windows doesn't send all messages via the message queue,
anyway...some messages - where order of processing is deemed
"unimportant" - are sent directly to the "window procedure"
without going via the message queue or message loop at
all...this is why Windows has the peculiar "window class"
requirement so that the "window procedure" address can be
registered before the window is created (a concept absent on X;
X is "client / server" - in a _real_ sense - from the ground
up...there is no "by-passing" present because this couldn't
really work over a remote connection...so, no "window
procedures" - at least, not formally...you may pass a message to
a procedure that's absolutely identical to a typical Windows
"window procedure"...but this is not enforced and you are free
to deal with it anywhere you like in the code...there is simply
an API to retrieve messages...thereafter, the application can
structure itself however it likes to respond to that message)...
How does this behaviour effect our "polling" / "non-polling"
distinction? Oh, brother, that's a damn good question...because
now _particular_ types of message are neither being blocked on
nor are they being "polled" for...Windows just delivers it
directly to the "window procedure", ignoring the "message loop"
completely...but, as we're not polling directly for this - we
can't - then it's also weighing in on the "non-polling" side of
things...
> This isn't the case, however.
No, I'd argue that it _IS_ the case...or, at least, typically is
the case...
"GetMessage" is the target API of concern here...this API is the
stem of the problem...it blocks...it can also optionally
"filter" for a particular message or it can be asked to return
any message...
Hence, though an application typically specifies "no filter",
let's consider when it specifically asks for that _particular_
message you're so concerned about...it won't unblock until
_only_ that "interesting" message you're worried about shows
up...
Do we call this "polling" or "non-polling" now? It's exactly the
type of "notification" you're talking about and it's _specific_
to a particular "interesting" message...there is no checking of
"availability"...
Surely, when you supply a "filter" like this, it's clearly
"non-polling"?
Or how about we write the "message loop" in a slightly different
way?
(slightly pseudo-code-y to be "neutral" to any particular
assembler...more concern about the _concept_ than actually
running it, basically :)
-----------------------------------------------
MsgLoop:
call WaitMessage
call PeekMessage, &Msg, NULL, NULL, NULL, PM_REMOVE
cmp [ Msg.message ], WM_QUIT
je ExitMsgLoop
call DispatchMessage, &Msg
jmp MsgLoop
-----------------------------------------------
Here, we're literally blocking until a message is available and
then pulling it off the message queue with the non-blocking
"PeekMessage" (and we can do so with confidence in that
"WaitMessage" won't return until there is a message
available...there is no "checking for availability of data",
you'll note ;)...
Behaviourly, this shouldn't differ from "GetMessage"...but we're
writing it this way to stress that we're calling "WaitMessage"
and blocking on the _event_ of a message being delivered...yes,
_ANY_ message, as "WaitMessage" has no
parameters..."PeekMessage" is non-blocking BUT, in this case,
due to the semantics of "WaitMessage", there's _always_ a
message for "PeekMessage" to pull off the queue...
Is this regarded as "polling" or "non-polling"?
Instead, we substitute "PeekMessage" for "GetMessage" in the
above...because "WaitMessage" is before it, then "GetMessage"
won't ever block, it'll always have a message to pull of the
queue...
Does this effect the determination?
How about if "GetMessage" is supplied a specific "filter" of
WM_MOUSEMOVE only ("WaitMessage" would be arguably redundent in
this case)?
Worse, the above has "NULL" for the HWND parameter, so it
accepts messages to _any_ of the thread's created windows...we
use "GetMessage" with a specific "filter"...now, if the
application only has _one_ window, it's "non-polling"...but if
it has multiple windows, it's now strangely "polling"...and the
code is NOT CHANGED in the slightest...it all relates solely to
how many "CreateWindow" calls were made _prior_ to the message
loop...
Many messages are delivered directly to the "window procedure",
completely ignoring the message loop...how does this effect the
determination?
And hutch's assertion was that _ALL_ of these instances -
because he said "message loop" in a completely generic sense -
are all "polling"?
You're far, far braver than I to be so firm and determined to
make such a concrete conclusion with such a confused
situation...there is, indeed, a particular perspective you could
take on particular types of "message loop" that I'd be satisfied
could arguably be called "polling" (but, at the same time, ends
up as a "matter of perspective" that if you are looking for
_any_ message rather than a particular one, it's "non-polling"
all over again)...
> While the Windows message
> loop does stretch the definition of "polling" a bit, the term
> still applies here.
Actually, is it "stretching" the definition...or is it, in fact,
making a _total mockery_ of the definition completely here,
because it's seemingly useless to even bother to attempt to make
the determination at all?
Remembering that it's only "polling" when you're looking at it
from the _particular_ perspective of a _particular_
message...and yet the exact same situation is also "non polling"
when your perspective is "all messages are equal in the eyes of
GetMessage" and you're not particularly concern with any
particular message but with any and all messages...
I mean, it's a bit of a weird definition when it's based on
something so subjective as what is and isn't an "interesting"
message...hey, I reckon WM_SETTINGSCHANGE is a really
"interesting" message...someone else might not...what on Earth
are we to make of such a term when it throws up such, quite
frankly, absurd notions such as this?
> As I've said in different posts, the
> "blocking" aspect is no different that having a machine
> assert the CPU hold line when you access a port, waiting
> for data to arrive at that port.
>
> Polling simply means that the application continues to
> "read" data from somewhere, until the desired data
> or state comes along.
BUT the typical "message loop" is absolutely 100%
non-discriminating...it keeps grabbing messages - "interesting"
or "uninteresting" - and keeps blasting them, whatever they are,
to "DispatchMessage"...it's NOT being "particular"
whatsoever..._EXCEPT_ for WM_QUIT to terminate the loop...
Now, on this note, let's consider something else...I have a
"for" loop...it's a simple one that initialises a variable to
zero at the beginning, increments the variable by one for each
iteration and tests for the variable reaching 10 as the
termination condition...from what you're saying, a "FOR" loop is
"polling"...so is a "while" loop (in fact, many message loops in
C / C++ literally stick "GetMessage" onto a while loop with
"DispatchMessage" inside...the return code of "GetMessage" is
even designed that way to naturally terminate a "while" loop
based on the return code...though, due to the possibility of an
error condition from incorrect parameters being supplied, this
is actually poor practice to do so...nevertheless, Microsoft's
own examples do this, despite them also being the ones to stress
how "poor programming" writing it this way actually is...go
figure ;)...
In fact, by this "definition", aren't _ALL_ loops "polling
loops", except for the sole exception of an infinite "forever"
loop...BUT, on the other hand, even the "forever" loop suddenly
becomes also a "polling loop" when there's an "if" and "break"
present too...
Hence, _ALL_ loops by this definition are "polling loops" -
except for a literal 100% unconditional infinite loop that does
not have any terminating conditions anywhere inside it (a loop
that should never be written under something like Windows,
anyhow) - because they all iterate until something is "read" -
be it hardware, be it a "counting" variable, etc. - which
triggers the terminating condition...
If this is the definition of "polling" then what use is a term
that simply means "loop", so long as it isn't an infinite loop?
Wouldn't the term "finite loop" make more sense?
If not, then what qualifier (that you've so far omitted) makes
"polling" any different a term to "finite loop"? What excludes a
simple "FOR K = 1 TO 10" style loop from also being "polling" on
the "K" variable?
I have to agree with Wannabee that if this is the true
definition of "polling" that we're to adhere to then the term
is, quite frankly, approaching uselessness in describing
anything of particular relevence...
> > "GetMessage" does NOT in any way check for the
> > "availability"...that was the point I was - admittedly,
perhaps
> > not in the clearest manner - trying to imply before when I
was
> > talking about how "GetMessage" (except for the sole
condition of
> > an error: Passing invalid parameters or whatever) does not
> > return without a message...there is no possibility (other
than
> > the error condition) for the instruction after "GetMessage"
not
> > to have a message to be processed...if there is no message
> > available, then the application stays _BLOCKED_...
>
> But GetMessage most certainly returns with data you're not
> interested in,
No, because I choose to be "interested" in _ALL_ messages
equally...and, without a "filter" applied (or in the case of
"WaitMessage" in any circumstances), the "perspective" of
"GetMessage" is also exactly this...it cares not about the
"interesting" nature of the message, just that there is or isn't
a message available...the application _can't_ care about how
"interesting" a message is...that's a subjective criterion and a
humanism...machines aren't "interested" in anything...for
certain, you've got to better define "interested" here...
After all, "interesting" / "uninteresting" is a subjective
criterion...more, it's a criterion that's likely to
change...that I'm "interest" in WM_PAINT while I'm trying to
perfect my painting routines but once dealt with, it becomes
"uninteresting" again, while I cope with WM_MOUSEMOVE...
And one "issue" here is that a typical "message loop" is
completely non-discriminating (other than for WM_QUIT)...it just
fires all messages at "DispatchMessage" regardless...and it's
the _window procedure_ - not the "message loop" - which is the
discriminating part that determines "interesting" from
"uninteresting" messages in whether it passes back to
"DefWindowProc" directly or not...
> in which case you've got to call it again to
> poll for the data you *are* interested in receiving.
Untrue; "GetMessage" accepts a "filter" argument...I can set the
"filter" to that particular message type...it won't, therefore,
return until I get my _specific_ "interesting" message (such a
loop is arguably useless in practice, though, because an
application has more than one message of "interest"...the
"filter" can deal with a "range" - it has a "min" and "max"
argument - but if the "interesting" message types aren't
contiguous then, indeed, this type of "GetMessage" call is
unlikely to be practically useful...BUT it is _possible_ and is
in the "nature" of "GetMessage"'s operation itself :)...
> The only thing that blocking does is make this process take
> longer.
Oh, seriously wrong; Blocking avoids applications consuming CPU
time over and over "polling" for a condition...when, rather, we
can implement a "don't call us, we'll call you" blocking scheme,
where, instead, applications take _NO_ CPU time whatsoever...
There is a "delay" brought about by the "overhead" of moving
threads from "blocked" to "active" and vice versa...but Windows
isn't designed as a "real-time" system...and the cost in CPU
time is absolutely nothing compared to applications sitting
around constantly eating into CPU time (coming up with 99% on
task manager :)...
If you think it's unimportant then, please, compose a "message
loop" that uses "PeekMessage" (and no other blocking API like
"WaitMessage") and then open up "Task Manager" to see how much
CPU time it takes (99% and only not 100% because the scheduler
is still kicking in periodically and, of course, if it takes
even _one_ clock cycle then, correctly, that's rounded down to
99%, not 100% ;)...you might even find the system becoming
sluggish because your application is eating up all the CPU
time...
And it's a _fatal_ move to click on the thread in Task Manager
and give it "realtime" priority...it'll lock out everything else
in the entire system completely...you won't be able to recover,
other than to tap the "reset" switch...
Blocking isn't simply "for fun"...it's a crucial point in the
entire design of a multi-tasking event-driven OS like Windows...
But, yes, I know you've done some embedded work, as I've done
too...possibly "realtime", was it? Yes, when you do have _full
control_ of the system, then such a "blocking" scheme is
needless "overhead"...throw the entire thing out and code it
down to the wire...oh, yes, I fully appreciate this "wolfgang"
attitude...but it's not right to presume that what makes sense
in such a particular system makes sense everywhere...when it
comes to the type of system that Windows is, then anything but a
blocking scheme would be wrong...and, in fact, Windows is crap
because it doesn't make things "asynchronous" enough in
places...
Windows is NOT a "real time" system and, to be fair, it has
never been pretended that it is..."real time" operations are a
specific, special requirement...and, commonly, it doesn't mix
with multi-tasking, GUI and so forth logically, let alone
physically...
> But I've never seen a definition of polling that
> prevents the application from being blocked for a while.
And I'm not proposing any such definition either...and I don't
think I saw anyone else do so either...
> Consider the following scenario:
>
> pollloop:
> mov eax, someMemoryAddress
> test eax, 1
> jne polllop
>
> This is polling, no?
Yes; This is "polling" (ignoring that you'd actually get a
"polllop not defined" error assembling this...I know, I
know...it was just a typo...I won't hold it against you
;)...it's similar to the "wait for vertical blank" VGA code I
posted before (except that we're "polling" on bit 4 of 3DAh
instead :)...
> Well suppose now that "someMemoryAddress" is in
> a page of memory that is not swapped in and this causes
> a page fault, and the OS doesn't bother returning until
> some other process actually writes data to that page.
> All of a sudden this is not polling?
No, it's still "polling"...and I don't propose that it wouldn't
be...
> I fail to see the difference between the MOV instruction
> in the example above and a call to GetMessage. Both block.
> Both don't return until some external event sets up some data
> for the application to test.
Actually, that's not quite right; Well, seeing as you've
insisted on "pedanticism" with terminology, then it's only right
to note that the "page fault" situation is NOT "blocking"...
The term "block" has a very specific meaning too, you know...it
involves re-designating a thread from the scheduler's "active
list" (to which it attributes CPU time) to its "blocked" list
(which are suspended threads, awaiting a particular condition
that "unblocks" them)...
As far as I'm aware, Windows does NOT "block" applications on a
"page fault"...it delays them, for sure...but does so in
consuming that thread's CPU time inside the kernel performing
the disk swapping...it would show up as red "Kernel time" on a
Task Manager graph...whereas, "blocking" does not register on
such a graph at all...
So, if we're insisting on "correct terminology" then we have to
also insist on the correct use of the term "block"...it's not
just a random word I've plucked out of the air...to "block" has
a very specific meaning regards how the scheduler treats the
thread...it literally _takes it off_ the "active list" and
places it on a "blocked" list instead, which is NOT scheduled
any CPU time whatsoever...these "blocked" threads are unblocked
by external events that fulfill certain conditions...so, when a
thread is "blocked on a message" then it is _literally moved_
from one of the scheduler's "lists" (the "active" list) to
another (the "blocked" list)...Windows itself "unblocks" the
thread as part of delivering the message to it...
You're indeed absolutely correct that the length of the delay is
completely irrelvent...but we're talking about a _different
nature_ of suspension here..."block" is a specific piece of OS
scheduler terminology that I use with specific intent, not
merely as some loose synonym for "delayed" or
"suspended"...check it up if you're not familiar with the
specific use of the term as I'm using it here...although, in
your case, I'd be mightily surprised if you didn't already
know...
> > Indeed, the application is NOT "checking for available data"
at
> > all...it is requesting an _asynchronous notification_ when
data
> > has become available and otherwise _BLOCKS_, consuming
> > absolutely no CPU time at all...it's an implicit "yield" to
call
> > "GetMessage"...
>
> It is not asynchronous. The app does not process the data
> prior to the GetMessage call, nor is it notified of new data
> once GetMessage returns until the app explicitly calls
GetMessage
> again. This is *synchronous* operation.
In which case, hutch's assertion was, indeed, wrong (although,
as noted to hutch, if his problem is just that using a
"blocking" scheme crashes on particular versions of Windows
then, well, if you can't do, then you can't do...that particular
problem and code wasn't the issue but more the assertions about
"message loops" always being "polling" loops)...
Again, we've a "perspective" thing...the operation of the
application is "synchronous" to the notification...but the
notificiation itself is asynchronous...the application responds
synchronously to the WM_MOUSEMOVE message being received...but
when the WM_MOUSEMOVE notification happens is _asynchronous_,
dependent on when the user feels like wiggling their mouse...I
attached "asynchronous" very specifically as an adjective of
"notification"...together, they are one noun...the application
_responds synchronously_ to the notification...the notification,
though, is an asynchronous notification because it depends on an
external event, such as a mouse movement, a key or button press,
a timer notification, etc....
> > No, sorry, it's NOT polling, pure and simple...this is a
fully
> > "asynchronous notification" system (or, at least, it should
> > be...Windows, as usual, is not a "role model" example :)...
>
> See my memory example above.
> And again, it is *not* asynchronous notification. That would
> require call backs or some sort of interrupt/signal mechanism.
Hello?!? The "window procedure" _IS_ a "callback" procedure (and
is directly called by Windows on occasion)...and, though it's
all "under the hood", the keyboard and mouse (and other
hardware) _ARE_ working on interrupts...the device drivers
retrieve this and propogate it upwards to the Windows kernel,
that abstracts this into its generic "messaging" system...hence,
a WM_MOUSEMOVE _IS_ an asynchronous notification and it _IS_ "on
interrupt" (as is the keyboard, as is the disks, as is the
soundcard, as is...well, not the video card typically...that's
the ***-up in PC design I always go on about...video lacks a
standardised interrupt for "historical reasons"...one of the
IRQs had to make way for the second PIC and, well, it got
connected to IRQ2, where the video IRQ was
designated...typically, PCs simply just didn't bother with the
vertical blank video interrupt thereafter)...but, indeed, the
_response_ is _synchronous_...
And even your memory example demonstrates this...the page of
memory will be marked "not present"...this triggers an
_exception_ (and an exception is merely an interrupt triggered
by the CPU itself)...the "page fault" exception handler is
effectively a "callback" function to deal with the need for disk
swapping...being an exception, this is a _synchronous
response_...but the interrupt system is an _asynchronous
notification_ system...
I'm differentiating quite delibrately - but it's important to
the operation and definitions here - between the actual
notification and the application response to that
notification...the notification is typically _asynchronous_ and
does often stem quite directly from the interrupt / exception
system and via "callbacks"...
Just because this happens inside the kernel and the device
drivers and is "abstracted" away from the application's
attentions doesn't mean it isn't happening, as I'm sure you can
appreciate...
> > Really, this is not merely some "personal opinion"...I did
> > courses on OS design at university and our textbooks
emphasised
> > that it's an integral part of multi-tasking OS design that
it
> > does NOT "poll"...a well-design and implemented
multi-tasking
> > OS - which Windows isn't overall but, on this particular
point
> > of "GetMessage", it does get it right for once - is
designed, as
> > best as is possible, to _NEVER_ "poll"...there is typically
> > never any reason to do so, as "asynchronous notification"
can
> > provide all the "synchronicity" with events that's
> > needed..."polling", indeed, should really only be reserved
for
> > situations where there's no other choice: a real-time system
> > where the "delay" in implementing blocking / unblocking or
> > whatever takes too unacceptably long...but this is a
"special
> > case"...
>
> Really, this is not some personal opinion. I've *taught* both
> operating systems, architecture, and hardware design courses
> at the local Universities.
Then review your material...you might have taught your students
the wrong material...
No, really, you know I'm not one of those who simply disagrees
with you just because it's you...I'm normally 100% behind most
of what you say...but, this time, I'm convinced you've jumped at
a shadow and made a minor ***-up here...
After all, your "definition" seems to have become so generalised
that it's now suggesting that _every_ loop, except for an
infinite loop, is "polling"...this seems so generalised as to be
quite useless in describing anything useful to anyone...
> Whether or not it is good design is something I will leave to
> others to debate,
Agreed; Whether it's good design or not is another matter...
And, frankly, is one of those "depends what you need"
things...something like an embedded "real-time" system would not
benefit from such a scheme...a typical multi-tasking GUI
benefits greatly from it...
But that is another separate topic...mentioned in passing but
not the central issue here...
> but what Hutch is describing certainly
> falls into the definition of "polling", even if that
definition is
> a bit stretched.
So "stretched" as to be a somewhat useless definition? A "for"
loop is "polling" by such a stretched definition (well, isn't
just your "memory example" with an initialisation beforehand, an
increment thrown into the loop and the test is "k == 10" or
whatever rather than a bit test ;)..._EVERY_ loop is a "polling
loop" by this definition, except for an infinite loop that tests
absolutely nothing because it always unconditionally loops
whatever the situation...and such an infinite loop with no
terminating condition at all is something that you should never
write under a system like Windows, anyway...
> Again, things would be different if he had
> called "WaitForSingleObject" or some other OS API that
> returned *only* when the desired event occured.
We _DO_ have this!
The "event" in question is "a message has been received"...yes,
_ANY_ messsage...that's why we've ommitted the "filter" argument
to "GetMessage" to exactly say that we want to block on _ANY_
message...
But, note, it's quite possible with "GetMessage" to be highly
specific, as it has a "hwnd" parameter to confine it to a
specific window only and a set of "filter" arguments to define a
particular range of messages we're interested in...and, of
course, this can be turned from a range to a single message type
by making the "min" and "max" range the same thing...
So, we _CAN_ be highly specific, if we really wanted to be...you
can call "GetMessage" specifying that it blocks until a
_particular_ window gets a _particular_ message...
And, indeed, it would return *only* when desired event
occurred...
That's exactly what I've been trying to say..."GetMessage" _IS_
such a blocking API...so, things _ARE_ different, as suggested:
It isn't "polling"...
> But as long
> as he executes a loop that says "give me the next message,
> oh, that data isn't what I wanted, loop back and repeat until
> I get the data I want", well, that sounds like polling to me.
But, typically, that _ISN'T_ code which describes the usual
"message loop"...usually, what's written is: "give me the next
message, blast to DispatchMessage, give me the next message,
blast to DispatchMessage"...it's completely non-discriminating
_except_ for termination when WM_QUIT is received...it's
normally the "window procedure" - unrelated to the "message
loop" - which does the "oh, that data isn't what I wanted, blast
to DefWindowProc for 'default processing'"...
And "GetMessage" is a blocking API that can be highly
discriminating to what message it is waiting for...BUT, if you
supply no "filter" then, implicitly, the "event" you're asking
for is "_any_ message received"...and "GetMessage" is exactly a
"WaitForSingleObject"-like API on the _specific_ "any message
received" event...to which the message loop typically is utterly
undiscriminating and passes it - "interesting" or
"uninteresting" - to "DispatchMessage"...the sole exception to
this is the terminating condition of receiving a WM_QUIT
message, which notifies the application to terminate itself
(although, technically, an application is at Liberty to simply
ignore this message, if it has no intention of ever
terminating...or, alternatively, an application - screensavers,
for example - terminate on some other message instead...WM_QUIT
is only a "standard" message to represent "please
terminate"...an application can refuse or create its own
differing terminating condition...which it can deal with in the
"message loop" or, alternatively, it could not bother and just
"ExitProcess" inside a message handler :)...
Consider:
------------------------------------
MsgLoop:
call GetMessage, &Msg, hwnd, WM_MOUSEMOVE, WM_MOUSEMOVE
call DispatchMessage, &Msg
jmp MsgLoop
WndProc:
cmp [ message ], WM_MOUSEMOVE
jne DefProcessing
cmp [ wParam ], MK_LBUTTON
jne DefProcessing
call ExitProcess, NULL
DefProcessing:
jmp DefWindowProc
------------------------------------
The "message loop" is a completely undiscriminating infinite
loop that _blocks_ on the highly specific _particular message_
of WM_MOUSEMOVE from the main "hwnd" window...and without
considering the message at all in any regard inside the message
loop, calls "DispatchMessage"...
This is a valid message loop that is completely defying your
"definition"...
And one that, so long as you're happy with terminating the
application ("ExitProcess") in a message handler rather than
waiting for WM_QUIT is a message loop that could be applied to
any program...asking for "any" message by specifying no "filter"
to "GetMessage" _still_ is blocking on *only* a desired
event...it's just that the desired event is "any message is
received"...this is quite correct because _THAT IS EXACTLY WHAT
WE SPECIFIED WE "DESIRED"_ in providing no "filter" argument to
"GetMessage"...hey, if you wanted only a particular message,
then you should have supplied a "filter" to tell Windows that!
Hence, this is a valid example of a "message loop" that could
conceivably be applied to any application where the "message
loop" can in no way - by your supplied "definition" - be
considered to be "polling"...
Better luck next time ;)...
> People can argue the relative merits of whether this is
> good design until they are blue in the face (and I have no
> opinion on that, to be honest), but what Hutch is doing
> certainly falls under the definition of polling.
Untraditional, yes.
> But still polling.
Ah, yes...what hutch is doing _is_, indeed, a case of "polling"
because he's done things like alter the "priorities" of the
threads and such to _make it_ a case of "polling"...
To clarify, the argument was not that you can't "poll" in a
"message loop" - that's incredibly easy, just use "PeekMessage"
instead - but hutch's assertion that all message loops are good
examples of "polling loops"...
As is often your defence, hutch implicitly made an "all"
assertion...hence, only _one_ example to the contrary disproves
the assertion...I've supplied that above...arguing this any
further and you're in danger of "doing a Betov", Randy...
Note that, in actual fact, hutch has clarified that he took the
"polling" rather than "blocking" solution because of a simple
_practical_ issue...he tried "blocking" and it didn't work on a
particular version of Windows...in which case, sure, the "work
around" is to _FORCE_ it to be a "polling loop" by altering
priorities and such...again, it's not the specific code or
solution that I'm debating (and I always said "if there's a good
reason for it, then, sure, go for it"...the fact that certain
versions of Windows crash if you take any other position - which
is kind of weird but I'm not particularly surprised where
Microsoft is involved - seems like an absolutely prefect "good
reason" to do it in such a "variant" way...I'd say it would be
"preferred" not to do so BUT if Windows ain't playing ball then
Windows ain't playing ball...we can't re-write Windows so we're
forced to re-write the application to "cover over" Windows'
failings, unfortunately)...
> > Is a "for" loop a "polling" loop? Because that iterates a
> > section of code until a particular condition is true...don't
let
> > the iteration confuse you: "GetMessage" _BLOCKS_ and the
> > "message loop" is a simple iterative loop that terminates
when
> > the message returned by "GetMessage" is WM_QUIT...
>
> If the for loop is iterating based on an external event, I
would
> say yes. Consider the following:
>
> mov ecx, timeoutValue
> loopTimeOut:
> in al, dx
> test al, 1
> loopnz loopTimeOut
>
> Is this a polling loop? Certainly it's a form of a FOR loop.
Ah, you ommitted the "external event" part from your definition
earlier...with it now properly introduced, the "definition" is
starting to make sense again...
> > That's what the difference is between "GetMessage" and
> > "PeekMessage" (with the PM_REMOVE flag supplied)...both
retrieve
> > a message off the message queue...the difference is that
> > "GetMessage" blocks until such a message is available, while
> > "PeekMessage" actually has "no message is available" return
> > code...you're "polling" when you use "PeekMessage" because
you
> > _are_ "checking for the availability of data"...you're NOT
doing
> > so with "GetMessage"...which totally surrenders control -
> > blocks - until it is awoken by an "asynchronous
notification"
> > that a message is available...
>
> The difference between the two is that GetMessage happens
> to return only when data of some sort is available. Same thing
> happens when a port asserts the hold line on the CPU and stops
> the CPU dead in its tracks until data is available. That's
still polling.
But you can specify a "filter" with "GetMessage" and get a
*particular* message as you stressed before...
> > With "GetMessage", it is simply NOT a polling loop...
>
> Yes, it *can* be. Certainly the way Hutch has defined
> things, it is. Now if the application handled *every* message
> that came along, rather than simply polling for the message it
> was interested in, this would be a different story.
Okay, to be clear...there was an assertion that _all_ message
loops were "polling loops" implicitly made by hutch ("go look at
a message loop to see what polling is"...no qualifier implies
that _any_ and _all_ message loops are equally "polling
loops")...
As there is the possibility of at least _ONE_ "message loop"
that does not qualify to the "polling loop" definitions given,
that assertion is demonstratably false...
There was no assertion that you couldn't write a "polling"
version of a "message loop" should you wish to...that's easy:
You use "PeekMessage" instead, which doesn't block on
anything...
You've pointed this out yourself in your own defences...when
there's an "all" (or "never")assertion, it merely takes _ONE_
example that violates the "all" (or "never") assertion to prove
it false...that was all I was concern with and I believe I've
supplied that example in this post...
> > Perhaps the API name is confusing you or something...note
that
> > if you called "WaitMessage" and then "PeekMessage" (with the
> > PM_REMOVE flag) - in that particular order - then this is
> > effectively the same as "GetMessage"...and "WaitMessage" is
a
> > blocking "asynchronous notification" API...one of the
"WaitXXX"
> > API group...it doesn't "poll", it asks for asynchronous
> > notification on the event of a pending message...
>
> Ah, but see, WaitForSingleObject is *not* polling.
I know; That's what I've been saying...it's a _blocking_
API...just like "WaitMessage"...just like "GetMessage" also...
> And, indeed, if you were waiting for *any* message, it would
> not be polling.
And this _IS_ what we're waiting for...
This can be seen by looking at the parameters supplied to
"GetMessage"...we've set the "min" and "max" filter arguments to
NULL, so we're _specifying explicitly_ that the event we want is
"_ANY_ message, please"...
> But the fact that it sits there spinning in a loop
> until the message it is interested in comes along, means that
it
> is polling.
No, you're confusing the discrimination that the _window
procedure_ makes with the lack of discrimination the "message
loop" has...it simply passes things to "DispatchMessage"...it is
the _WINDOW PROCEDURE_ that decides what is "interesting" and
what is "uninteresting"...
A "message loop" does also typically look for WM_QUIT to
terminate...but, alternatively, the "message loop" can simply
not bother and, instead, the window procedure carries the
termination code instead (in response to a WM_QUIT, possibly)...
This isn't C...an application ends because of "ExitProcess", not
because it "falls off the end" of a procedure...and you could
always be a touch "renegade" and do an insane "JMP" from the
window procedure back to terminating code in the "main"
procedure...assembly language is only "structured programming"
if you choose it to be so (a good idea, mind you :)...and such
"tricks" are also possible even in "structured programming"
HLLs, anyway...
> This means that it's wasting CPU resources (clock cycles)
> testing for the right message for as long as the wrong message
> comes along.
Yeah, well...I've always said so that Windows has a _design
flaw_ in this regard that it insists on sending all messages to
all windows regardless...actually, that's another piece of bad
design that it sends to _windows_, rather than applications so
you have the bizarre "hidden" windows lying around just to pick
up messages with no intention of ever displaying output via
these "windows" (in X, this is more sensibly dealt with by
having two window types: InputOnlyWindow and
InputOutputWindow...also, X does allow an application to also
specify what is and isn't "interesting" message-wise and doesn't
bother even attempting to deliver messages the application has
declared "uninteresting"...it's a touch not "fine grained"
enough for my tastes but X has at least got the basic idea
correct :)...
But the "wasted cycles" for a _blocking_ "GetMesssage" style
loop compared to a non-blocking "PeekMessage" style loop is
quite clear with Task Manager: The non-blocking "PeekMessage"
consumes all excess clock cycles (reading 99% when nothing else
is going on)...whereas, the same application using "GetMessage"
registers 0% CPU time and, if nothing else is happening, the
"system idle thread" registers the 99% instead (meaning 99% is
"available" for use by any application in the system but, well,
if there is nothing else then it just goes "idle"...which is
also good because it typically issues "HLT" and saves you
energy, giving the CPU a chance to cool down a little ;)...
> Whether or not "WaitForSingleObject" is a better
> solution (which wouldn't waste those cycles and *would* block
> until the desired message comes along) is not something I can
> answer as I've not paid close enough attention to this debate.
Perhaps you should have paid more attention to the debate from
the perspective of realising exactly what it was I was arguing
against...I also couldn't give a crap about hutch's program...it
was his "all message loops are polling loops" assertion I wanted
to correct...it is NOT "all" and, rather, most are _blocking_ to
not be "polling" as much as possible...
> I can tell you this, though. No matter what your OS textbook
says,
> sometimes polling *is* the most efficient way to handle
things.
Yes, I know...again, I wasn't actually saying that...I was just
talking about the "blocking" mechanism being efficient in a
particular circumstance...by the same token, if you need to be
"real time" and respond as instantly as possible, "polling" is,
indeed, the most efficient method...
> Particularly in real-time systems where the latencies
associated
> with interrupt handlers, message passing, and other such
goodies
> can mean that you deal with an event after the "drop-dead"
time.
Yup; I've dealt with "real time" embedded systems too...I'm
aware that it's often the more efficient thing in those
particular circumstances...indeed, it was a "mission critical"
real-time system that had to react incredibly quickly with quite
a complicated calculation...it was literally running against a
clock to work out what to do before a person got injured or
killed...latency was a particularly nasty "nasty" to wipe out of
the equations as far as possible...literally a "life or death"
issue in this particular case...
But, obviously, Windows - the system in question - is not such a
system...the requirements and expectations are different...it's
never been intended as anything like "real time"...rather the
efficient management of resources tends to be a higher
priority...although, yes, this is somewhat laughable where
Microsoft are involved...they can't even do that part
right...but, well, that's another separate "novel" I'll probably
post later this week ;)...
Beth :)
- Next message: Phil Carmody: "Re: Why RosAsm Breaks on a large number of symbols"
- Previous message: J.Mo: "Re: ASM vs HLL : absurd war"
- In reply to: Randall Hyde: "Re: Why RosAsm Breaks on a large number of symbols"
- Next in thread: Phil Carmody: "Re: Why RosAsm Breaks on a large number of symbols"
- Reply: Phil Carmody: "Re: Why RosAsm Breaks on a large number of symbols"
- Reply: hutch--: "Re: Why RosAsm Breaks on a large number of symbols"
- Reply: The Wannabee: "Re: Why RosAsm Breaks on a large number of symbols"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]