I didn't get much farther by myself, but I recently ran across a snippet from someone who seems to know what they're doing. The quote is from Jason Schroeder. In case you're wondering how this fits into my original question, I found a stack trace in a dump file that shows that SendMessageW calls NtUserMessageCall. Here is the quote: user32!NtUserMessageCall is just a stub that calls into win32k.sys, so if you want to see what your thread is "really" doing, hook up a kernel debugger... Reference: http://ask.metafilter.com/75491/Why-is-SendMessage-blocking-on-NtUserMessageCall[^]
waldemar sauer aitmetis com
Posts
-
Thread Message Queue -
How to prevent listview from redrawing when setting its columns width?Try to subclass the window, and ignore WM_PAINT messages until column resizing is done. Good luck -Waldemar
-
Thread Message QueueHow does the Windows thread message queue work? I can't seem to find good information on this topic anywhere. I had a look at how the Wine project does this, and it looks like they are using a Linux file descriptor (a named pipe, I'm guessing) to implement their message queue. They might have chosen to do their thread queue differently than how MS chose to do it natively, but I'm not sure. My situation: I have a crash dump, and I have a suspicion that the UI thread of this application has a long list of requests that are blocked on the UI thread, waiting to be serviced. So I was hoping that there might be some simple number somewhere in the dump that tells me how many requests are still waiting in queue, or maybe at least some decent way to find that out from within WinDbg. -Waldemar
-
Office PranksLong live Dvorak!
-
False selection...It's hard for me to tell what the answer would be inside a Java interpreter. I suspect that the difference will be small. I doubt that declaring local variables vs. not declaring will actually make a difference in C/C++. Local variables get assigned machine registers, and they may actually not require stack locations at all. In fact, with a decent optimizing compiler, the following snippets will compile to the same code:
void fx(int x)
{
doSomethingWithX(x);
}and
void fx(int x)
{
int descriptionForX = x;
doSomethingWithX(descriptionForX);
}The reason is that the 'descriptionForX' variable will be coalesced so that it uses the same register as x, and will subsequently be removed by the compiler.
-
False selection...It's all in the first block of code. test1() vs. test2(). The examples are a bit contrived, and might not look like the original question anymore. For one thing, I just assume that you magically know the result of "getWidth()", etc. Basically, I try to pit the concept of declaring boolean variables versus returning false early against each other.
-
False selection...This format definitely has an advantage in that if you suspect displayModesMatch of doing something wrong, or otherwise just want to know what it is doing, you only need to set one breakpoint. I guess both approaches have their merits. But before we just go ahead and assume that this way is better than that way, let's see how C++ would have done this task. I found the results quite surprising. To simplify, I used the following code snippet:
bool test1(int dim1, int dim2, int depth1, int depth2, int refresh1, int refresh2)
{
bool isEqDim = (dim1 == dim2);
bool isEqDepth = (depth1 == depth2);
bool isEqRefresh = (refresh1 == refresh2);
return isEqDim && isEqDepth && isEqRefresh;
}bool test2(int dim1, int dim2, int depth1, int depth2, int refresh1, int refresh2)
{
if (dim1 != dim2)
return false;
if (depth1 != depth2)
return false;
if (refresh1 != refresh2)
return false;
return true;
}void trialrig()
{
int dim1, dim2, depth1, depth2, refresh1, refresh2;
scanf("%i", &dim1);
scanf("%i", &dim2);
scanf("%i", &depth1);
scanf("%i", &depth2);
scanf("%i", &refresh1);
scanf("%i", &refresh2);
bool b1_1 = test1(dim1, dim2, depth1, depth2, refresh1, refresh2);
bool b2_1 = test2(dim1, dim2, depth1, depth2, refresh1, refresh2);
if (b1_1)
printf("b1 is true\n");
if (b2_1)
printf("b2 is true\n");
}The scanf's were important, because if they're not there, my compiler just optimized both the test functions out of existence. During compiling, some of these were inlined, so I have to compensate somewhat. So for simplicity, assume that both code blocks below are prefixed with these instructions:
mov eax, DWORD PTR \_dim1$\[esp+88\] mov ecx, DWORD PTR \_dim2$\[esp+88\] mov esi, DWORD PTR \_depth1$\[esp+88\] mov edi, DWORD PTR \_depth2$\[esp+88\] mov ebx, DWORD PTR \_refresh1$\[esp+88\] mov ebp, DWORD PTR \_refresh2$\[esp+88\]
In release build, it produced the following for one of the two functions (excluding the preamble above):
cmp eax, ecx jne SHORT $LN7@test12 cmp esi, edi jne SHORT $LN7@test12 cmp ebx, ebp jne SHORT $LN7@test12 mov dl, 1 jmp SHORT $LN8@test12
$LN7@test12:
xor dl, dl
$LN8@test12:And the following code for the other function:
cmp eax, ecx je
-
Old WindowsConsidering the post before you was: "Programmers shouldn't build UIs.", I think you can safely ignore most of this thread. Just a flame war waiting to happen. Managers that are worth their salt don't care about how you press/click/type 'save' as long as the job gets done. The occasional person who uses the menus are maybe a good reminder that not every one, heck not even all developers, think about achieving the same thing in the same way. For us it's maybe a personal choice, but I'm sure there are lots of people out there that are completely unaware of keyboard shortcuts.
-
swap two values withou using temp. storageHe doesn't. Note the signature: "xswap(A**&** a". But there are a number of flaws in handling things this way. For starters, the Visual C++ compiler (and I presume everyone else will also be in this category) compiles two versions for xswap, even if the only difference is the size of the array, so int a[1024], b[1024], c[2048], d[2048]; xswap(a, b); xswap(c, d); produces two copies of xswap. But let's not stop there. The assembly output for the xor version is horrible. I didn't check the + and - version above, but it will probably be just as bad. Visual C++ (and presumably other compilers also) does what looks like the right thing if you use a simple temporary, namely something like this: mov eax, [current ptr for a] mov edx, [current ptr for b] mov [current ptr for b], eax mov [current ptr for a], edx Temporaries are definitely the way to go. They're more susceptible to compiler optimizations such as coalescing, and if you prefer, some style of XMM hand optimization. I see pxor has the option for an m128 argument, so maybe there's something there. I'm not even sure why this would be an interview question. Maybe a better interview question is: In how many ways is the xor solution a bad idea?