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.