3-1
/*
* Busy2.c
*
* Sample code for Multithreading Applications in Win32
* This sample is mentioned in the text but there is
* no associated listing in the book.
*
* Run a busy loop and a worker thread at
* the same time. This program is intended
* to be monitored by PerfMon in Windows NT.
* You will need to Ctrl-C out to exit.
*
* Build command: cl /MD busywait.c
*/
#define WIN32_LEAN_AND_MEAN
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>
#include "MtVerify.h"
DWORD WINAPI ThreadFunc(LPVOID);
int main()
{
HANDLE hThrd;
DWORD exitCode = 0;
DWORD threadId;
DWORD begin;
DWORD elapsed;
puts("Busy2 is designed to use up CPU time.");
puts("Press Ctrl+C to exit.");
begin = GetTickCount();
MTVERIFY( hThrd = CreateThread(NULL,
0,
ThreadFunc,
(LPVOID)1,
0,
&threadId )
);
/* This busy loop chews up lots of CPU time */
for (;;)
{
GetExitCodeThread(hThrd, &exitCode);
if ( exitCode != STILL_ACTIVE )
break;
}
elapsed = GetTickCount()-begin;
printf("Thread + busy loop took: %d.%.03d seconds\n",
elapsed/1000, elapsed%1000);
MTVERIFY( CloseHandle(hThrd) );
return EXIT_SUCCESS;
}
/*
* Cute little busy work routine that computes the value
* of PI using probability. Highly dependent on having
* a good random number generator (rand is iffy)
*/
DWORD WINAPI ThreadFunc(LPVOID n)
{
int i;
int inside = 0;
double val;
UNREFERENCED_PARAMETER(n);
/* Seed the random-number generator */
srand( (unsigned)time( NULL ) );
for (i=0; i<100000000; i++)
{
double x = (double)(rand())/RAND_MAX;
double y = (double)(rand())/RAND_MAX;
if ( (x*x + y*y) <= 1.0 )
inside++;
}
val = (double)inside / i;
printf("PI = %.4g\n", val*4);
return 0;
}
od
00401000 /$ 81EC 10010000 sub esp, 110
00401006 |. 53 push ebx
00401007 |. 55 push ebp
00401008 |. 56 push esi
00401009 |. 8B35 34204000 mov esi, dword ptr [<&MSVCRTD.puts>] ; MSVCRTD.puts
0040100F |. 57 push edi
00401010 |. 68 F8304000 push 004030F8 ; /s = "Busy2 is designed to use up CPU time."
00401015 |. C74424 14 000>mov dword ptr [esp+14], 0 ; |
0040101D |. FFD6 call esi ; \puts
0040101F |. 68 E0304000 push 004030E0 ; ASCII "Press Ctrl+C to exit."
00401024 |. FFD6 call esi
00401026 |. 8B1D 20204000 mov ebx, dword ptr [<&KERNEL32.GetTi>; kernel32.GetTickCount
0040102C |. 83C4 08 add esp, 8
0040102F |. FFD3 call ebx ; [GetTickCount
00401031 |. 8BE8 mov ebp, eax
00401033 |. 8D4424 1C lea eax, dword ptr [esp+1C]
00401037 |. 50 push eax ; /pThreadId
00401038 |. 6A 00 push 0 ; |CreationFlags = 0
0040103A |. 6A 01 push 1 ; |pThreadParm = 00000001
0040103C |. 68 C0114000 push 004011C0 ; |ThreadFunction = Busy2.004011C0
00401041 |. 6A 00 push 0 ; |StackSize = 0
00401043 |. 6A 00 push 0 ; |pSecurity = NULL
00401045 |. FF15 1C204000 call dword ptr [<&KERNEL32.CreateThre>; \CreateThread
0040104B |. 8BF0 mov esi, eax
0040104D |. 85F6 test esi, esi
0040104F |. 75 7B jnz short 004010CC
00401051 |. FF15 18204000 call dword ptr [<&KERNEL32.GetLastErr>; [GetLastError
00401057 |. 56 push esi ; /Arguments
00401058 |. 8D4C24 18 lea ecx, dword ptr [esp+18] ; |
0040105C |. 56 push esi ; |BufSize
0040105D |. 51 push ecx ; |Buffer
0040105E |. 56 push esi ; |LanguageId
0040105F |. 50 push eax ; |MessageId
00401060 |. 56 push esi ; |pSource
00401061 |. 68 00110000 push 1100 ; |Flags = ALLOCATE_BUFFER|FROM_SYSTEM|0
00401066 |. FF15 14204000 call dword ptr [<&KERNEL32.FormatMess>; \FormatMessageA
0040106C |. 8B5424 14 mov edx, dword ptr [esp+14]
00401070 |. 8D4424 20 lea eax, dword ptr [esp+20]
00401074 |. 52 push edx ; /<%s>
00401075 |. 68 9C304000 push 0040309C ; |<%s> = "hThrd = CreateThread(NULL, 0, ThreadFunc, (LPVOID)1, 0, &threadId )"
0040107A |. 68 94304000 push 00403094 ; |<%s> = "Busy2.c"
0040107F |. 6A 2B push 2B ; |<%d> = 2B (43.)
00401081 |. 68 50304000 push 00403050 ; |Format = LF,"The following call failed at line %d in %s:",LF,LF," %s",LF,LF,"Reason: %s",LF,""
00401086 |. 50 push eax ; |s
00401087 |. FF15 74204000 call dword ptr [<&USER32.wsprintfA>] ; \wsprintfA
0040108D |. 83C4 18 add esp, 18
00401090 |. 8D4C24 18 lea ecx, dword ptr [esp+18]
00401094 |. 8D7C24 20 lea edi, dword ptr [esp+20]
00401098 |. 33C0 xor eax, eax
0040109A |. 56 push esi ; /pOverlapped
0040109B |. 51 push ecx ; |pBytesWritten
0040109C |. 83C9 FF or ecx, FFFFFFFF ; |
0040109F |. 8D5424 28 lea edx, dword ptr [esp+28] ; |
004010A3 |. F2:AE repne scas byte ptr es:[edi] ; |
004010A5 |. F7D1 not ecx ; |
004010A7 |. 49 dec ecx ; |
004010A8 |. 51 push ecx ; |nBytesToWrite
004010A9 |. 52 push edx ; |Buffer
004010AA |. 6A F4 push -0C ; |/DevType = STD_ERROR_HANDLE
004010AC |. FF15 10204000 call dword ptr [<&KERNEL32.GetStdHand>; |\GetStdHandle
004010B2 |. 50 push eax ; |hFile
004010B3 |. FF15 0C204000 call dword ptr [<&KERNEL32.WriteFile>>; \WriteFile
004010B9 |. 68 B80B0000 push 0BB8 ; /Timeout = 3000. ms
004010BE |. FF15 08204000 call dword ptr [<&KERNEL32.Sleep>] ; \Sleep
004010C4 |. 6A 01 push 1 ; /status = 1
004010C6 |. FF15 30204000 call dword ptr [<&MSVCRTD.exit>] ; \exit
004010CC |> 8B3D 04204000 mov edi, dword ptr [<&KERNEL32.GetEx>; kernel32.GetExitCodeThread
004010D2 |. 8D4424 10 lea eax, dword ptr [esp+10]
004010D6 |. 50 push eax ; /pExitCode
004010D7 |. 56 push esi ; |hThread
004010D8 |. FFD7 call edi ; \GetExitCodeThread
004010DA |. 817C24 10 030>cmp dword ptr [esp+10], 103
004010E2 |. 75 12 jnz short 004010F6
004010E4 |> 8D4C24 10 /lea ecx, dword ptr [esp+10]
004010E8 |. 51 |push ecx
004010E9 |. 56 |push esi
004010EA |. FFD7 |call edi ; kernel32.GetExitCodeThread
004010EC |. 817C24 10 030>|cmp dword ptr [esp+10], 103
004010F4 |.^ 74 EE \je short 004010E4
004010F6 |> FFD3 call ebx
004010F8 |. 8BC8 mov ecx, eax
004010FA |. 33D2 xor edx, edx
004010FC |. 2BCD sub ecx, ebp
004010FE |. BF E8030000 mov edi, 3E8
00401103 |. 8BC1 mov eax, ecx
00401105 |. F7F7 div edi
00401107 |. B8 D34D6210 mov eax, 10624DD3
0040110C |. 52 push edx ; /<%.03d>
0040110D |. F7E1 mul ecx ; |
0040110F |. C1EA 06 shr edx, 6 ; |
00401112 |. 52 push edx ; |<%d>
00401113 |. 68 24304000 push 00403024 ; |format = "Thread + busy loop took: %d.%.03d seconds",LF,""
00401118 |. FF15 2C204000 call dword ptr [<&MSVCRTD.printf>] ; \printf
0040111E |. 83C4 0C add esp, 0C
00401121 |. 56 push esi ; /hObject
00401122 |. FF15 00204000 call dword ptr [<&KERNEL32.CloseHandl>; \CloseHandle
00401128 |. 85C0 test eax, eax
0040112A |. 0F85 80000000 jnz 004011B0
00401130 |. FF15 18204000 call dword ptr [<&KERNEL32.GetLastErr>; [GetLastError
00401136 |. 6A 00 push 0 ; /Arguments = NULL
00401138 |. 8D5424 18 lea edx, dword ptr [esp+18] ; |
0040113C |. 6A 00 push 0 ; |BufSize = 0
0040113E |. 52 push edx ; |Buffer
0040113F |. 6A 00 push 0 ; |LanguageId = 0 (LANG_NEUTRAL)
00401141 |. 50 push eax ; |MessageId
00401142 |. 6A 00 push 0 ; |pSource = NULL
00401144 |. 68 00110000 push 1100 ; |Flags = ALLOCATE_BUFFER|FROM_SYSTEM|0
00401149 |. FF15 14204000 call dword ptr [<&KERNEL32.FormatMess>; \FormatMessageA
0040114F |. 8B4424 14 mov eax, dword ptr [esp+14]
00401153 |. 8D4C24 20 lea ecx, dword ptr [esp+20]
00401157 |. 50 push eax ; /<%s>
00401158 |. 68 10304000 push 00403010 ; |<%s> = "CloseHandle(hThrd)"
0040115D |. 68 94304000 push 00403094 ; |<%s> = "Busy2.c"
00401162 |. 6A 38 push 38 ; |<%d> = 38 (56.)
00401164 |. 68 50304000 push 00403050 ; |Format = LF,"The following call failed at line %d in %s:",LF,LF," %s",LF,LF,"Reason: %s",LF,""
00401169 |. 51 push ecx ; |s
0040116A |. FF15 74204000 call dword ptr [<&USER32.wsprintfA>] ; \wsprintfA
00401170 |. 8D7C24 38 lea edi, dword ptr [esp+38]
00401174 |. 83C9 FF or ecx, FFFFFFFF
00401177 |. 33C0 xor eax, eax
00401179 |. 83C4 18 add esp, 18
0040117C |. F2:AE repne scas byte ptr es:[edi]
0040117E |. F7D1 not ecx
00401180 |. 8D5424 18 lea edx, dword ptr [esp+18]
00401184 |. 6A 00 push 0 ; /pOverlapped = NULL
00401186 |. 49 dec ecx ; |
00401187 |. 52 push edx ; |pBytesWritten
00401188 |. 8D4424 28 lea eax, dword ptr [esp+28] ; |
0040118C |. 51 push ecx ; |nBytesToWrite
0040118D |. 50 push eax ; |Buffer
0040118E |. 6A F4 push -0C ; |/DevType = STD_ERROR_HANDLE
00401190 |. FF15 10204000 call dword ptr [<&KERNEL32.GetStdHand>; |\GetStdHandle
00401196 |. 50 push eax ; |hFile
00401197 |. FF15 0C204000 call dword ptr [<&KERNEL32.WriteFile>>; \WriteFile
0040119D |. 68 B80B0000 push 0BB8 ; /Timeout = 3000. ms
004011A2 |. FF15 08204000 call dword ptr [<&KERNEL32.Sleep>] ; \Sleep
004011A8 |. 6A 01 push 1 ; /status = 1
004011AA |. FF15 30204000 call dword ptr [<&MSVCRTD.exit>] ; \exit
004011B0 |> 5F pop edi
004011B1 |. 5E pop esi
004011B2 |. 5D pop ebp
004011B3 |. 33C0 xor eax, eax
004011B5 |. 5B pop ebx
004011B6 |. 81C4 10010000 add esp, 110
004011BC \. C3 retn
thread
004011C0 /. 55 push ebp
004011C1 |. 8BEC mov ebp, esp
004011C3 |. 83E4 F8 and esp, FFFFFFF8
004011C6 |. 83EC 0C sub esp, 0C
004011C9 |. 53 push ebx
004011CA |. 56 push esi
004011CB |. 57 push edi
004011CC |. 33FF xor edi, edi
004011CE |. 57 push edi ; /timer => NULL
004011CF |. 897C24 10 mov dword ptr [esp+10], edi ; |
004011D3 |. FF15 40204000 call dword ptr [<&MSVCRTD.time>] ; \time
004011D9 |. 50 push eax ; /seed
004011DA |. FF15 3C204000 call dword ptr [<&MSVCRTD.srand>] ; \srand
004011E0 |. 8B1D 38204000 mov ebx, dword ptr [<&MSVCRTD.rand>] ; MSVCRTD.rand
004011E6 |. 83C4 08 add esp, 8
004011E9 |. BE 00E1F505 mov esi, 5F5E100
004011EE |> FFD3 /call ebx
004011F0 |. 894424 0C |mov dword ptr [esp+C], eax
004011F4 |. DB4424 0C |fild dword ptr [esp+C]
004011F8 |. DC0D 98204000 |fmul qword ptr [402098]
004011FE |. DD5C24 10 |fstp qword ptr [esp+10]
00401202 |. FFD3 |call ebx
00401204 |. 894424 0C |mov dword ptr [esp+C], eax
00401208 |. DB4424 0C |fild dword ptr [esp+C]
0040120C |. DC0D 98204000 |fmul qword ptr [402098]
00401212 |. D9C0 |fld st
00401214 |. D8C9 |fmul st, st(1)
00401216 |. DD4424 10 |fld qword ptr [esp+10]
0040121A |. DC4C24 10 |fmul qword ptr [esp+10]
0040121E |. DEC1 |faddp st(1), st
00401220 |. DC1D 90204000 |fcomp qword ptr [402090]
00401226 |. DFE0 |fstsw ax
00401228 |. F6C4 41 |test ah, 41
0040122B |. DDD8 |fstp st
0040122D |. 74 01 |je short 00401230
0040122F |. 47 |inc edi
00401230 |> 4E |dec esi
00401231 |.^ 75 BB \jnz short 004011EE
00401233 |. 897C24 0C mov dword ptr [esp+C], edi
00401237 |. 83EC 08 sub esp, 8
0040123A |. DB4424 14 fild dword ptr [esp+14] ; |
0040123E |. DC0D 88204000 fmul qword ptr [402088] ; |
00401244 |. DC0D 80204000 fmul qword ptr [402080] ; |
0040124A |. DD1C24 fstp qword ptr [esp] ; |
0040124D |. 68 20314000 push 00403120 ; |format = "PI = %.4g",LF,""
00401252 |. FF15 2C204000 call dword ptr [<&MSVCRTD.printf>] ; \printf
00401258 |. 83C4 0C add esp, 0C
0040125B |. 33C0 xor eax, eax
0040125D |. 5F pop edi
0040125E |. 5E pop esi
0040125F |. 5B pop ebx
00401260 |. 8BE5 mov esp, ebp
00401262 |. 5D pop ebp
00401263 \. C2 0400 retn 4
ida