Figure 4 BadThrd.cpp
// BadThrd.cpp : Defines the entry point for the application.
#include "stdafx.h"
//
// Global variables.
//
int x;
//
DWORD WINAPI ThreadMainA(LPVOID pData)
{
TCHAR tch[256];
DWORD dwTickStart = GetTickCount();
int i;
for (x = 2000000; x >0; x)
{
// Empty loop on purpose.
i = x;
}
DWORD dwTickEnd = GetTickCount();
DWORD dwTickCount = dwTickEnd - dwTickStart;
wsprintf(tch, _T("Counts for 200000 iterations is %d"), dwTickCount);
MessageBox(NULL, tch, _T("BadThrd"), MB_OK);
return 0;
}
//
DWORD WINAPI ThreadMainB(LPVOID pData)
{
TCHAR tch[256];
DWORD dwTickStart = GetTickCount();
int i;
for (x = 0; x < 2000000; x++)
{
// Empty loop on purpose.
i = x;
}
DWORD dwTickEnd = GetTickCount();
DWORD dwTickCount = dwTickEnd - dwTickStart;
wsprintf(tch, _T("Counts for 200000 iterations is %d"), dwTickCount);
MessageBox(NULL, tch, _T("BadThrd"), MB_OK);
return 0;
}
//
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
DWORD dwA;
DWORD dwB;
HANDLE hThreadA = CreateThread(NULL, NULL, ThreadMainA, NULL, NULL,
&dwA);
HANDLE hThreadB = CreateThread(NULL, NULL, ThreadMainB, NULL, NULL,
&dwB);
MessageBox(NULL, _T("Done"), _T("BadThrd"), MB_OK);
return 0;
}
Figure 5 GoodThrd.cpp
// GoodThrd.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
//
// Global variables.
//
int x;
CRITICAL_SECTION cs;
//
DWORD WINAPI ThreadMainA(LPVOID pData)
{
TCHAR tch[256];
DWORD dwTickStart = GetTickCount();
int i;
EnterCriticalSection(&cs);
for (x = 2000000; x >0; x)
{
// Empty loop on purpose.
i = x;
}
LeaveCriticalSection(&cs);
DWORD dwTickEnd = GetTickCount();
DWORD dwTickCount = dwTickEnd - dwTickStart;
wsprintf(tch, _T("Counts for 200000 iterations is %d"), dwTickCount);
MessageBox(NULL, tch, _T("GoodThrd"), MB_OK);
return 0;
}
//
DWORD WINAPI ThreadMainB(LPVOID pData)
{
TCHAR tch[256];
DWORD dwTickStart = GetTickCount();
int i;
EnterCriticalSection(&cs);
for (x = 0; x < 2000000; x++)
{
// Empty loop on purpose.
i = x;
}
LeaveCriticalSection(&cs);
DWORD dwTickEnd = GetTickCount();
DWORD dwTickCount = dwTickEnd - dwTickStart;
wsprintf(tch, _T("Counts for 200000 iterations is %d"), dwTickCount);
MessageBox(NULL, tch, _T("GoodThrd"), MB_OK);
return 0;
}
//
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
DWORD dwA;
DWORD dwB;
// Setup critical section for our use.
InitializeCriticalSection(&cs);
// Do our work.
HANDLE hThreadA = CreateThread(NULL, NULL, ThreadMainA, NULL, NULL,
&dwA);
HANDLE hThreadB = CreateThread(NULL, NULL, ThreadMainB, NULL, NULL,
&dwB);
// Free up critical section.
DeleteCriticalSection(&cs);
MessageBox(NULL, _T("Done"), _T("GoodThrd"), MB_OK);
return 0;
}
Figure 6 New Real-time Functions in Windows CE
Function |
Description |
CeSetThreadPriority, CeGetThreadPriority |
Accesses the 256 thread priorities that are supported on Windows CE 3.0. You can still call the older functions, SetThreadPriority and GetThreadPriority, but they will only allow you to access eight thread priorities, which correspond to the lowest priorities in Windows CE 3.0. |
TryEnterCriticalSection |
Lets you attempt to acquire a critical section without having to block if the critical section is already owned. Previously, EnterCriticalSection was the only function that Windows CE supported for acquiring critical sections, and it always blocks when a critical section is already owned. |
CeSetThreadQuantum, CeGetThreadQuantum |
These Windows CE-specific functions let you set or query the duration of the preemption timer. This timer determines how long the scheduler allows a thread to run before interrupting it to allow a thread with the same priority to run. Higher-priority threads always interrupt lower-priority threads. |
CreateSemaphore, ReleaseSemphore |
Microsoft has added support for semaphores in Windows CE 3.0. |