Listing 7 Implements main logic of example program BIGJOB.cpp

/* define externals and prototypes */
#include "cschlr.hpp"

VOID Timer(void);
VOID Big(void);
VOID PaintWindow( PGPFPARMS pGpfParms);
VOID SelectRep( PGPFPARMS pGpfParms);
VOID StartSalvage( PGPFPARMS pGpfParms);
VOID AbortSalvage( PGPFPARMS pGpfParms);
VOID CreateThreads(VOID);
VOID PeekMessageLoop(MSG * pMsg, Cschlr *pTask);
static double Savage(double x);

enum Status {IDLE, RUNNING, DONE, ABORTED};

SHORT idCommand = ID_REP10;             //iteration command
short nIterations;                      //no. of iterations
Status status = IDLE;                   //current status
SHORT rep[4] = {10, 100, 1000, 10000};  //iteration values
time_t lStart;                          //start time
time_t lTime;                           //command total time
BOOL fContinue;                         //continue flag

int thdtimer, thdbig;                   //thread objects
Csemq *semjob, *semtimer;               //semaphore objects
const int STACKSIZE = 4096;             //stack size
Cschlr mtask;                           //scheduler object

/* Used to execute the Salvage benchmark once */
static double Savage(double x)
{
  return tan(atan(exp(log(sqrt(x * x))))) + 1.0;
}

/* Used to diaply the main window to reflect the state of executeion */
VOID PaintWindow( PGPFPARMS pGpfParms)
{
  static char *szFormat[]: {
       "Idling...",
       "Running... %ld seconds passed",
       "Completed in %ld seconds: %d repetitions",
       "Aborted after %ld seconds"
       };

  RECT rect;
  char szMsg[50];
  
  GetClientRect(pGpfParms->hwnd, &rect);
  wsprintf(szMsg, szFormat[status], lTime, nIterations);
  DrawText(pGpfParms->hdc, szMsg, -1, &rect,
          DT_SINGLELINE | DT_CENTER | DT_VCENTER);

}

/* Timer thread function to display the status report
  every 5 seconds */
VOID Timer(VOID)
{
  int i;

  while (1)
       {
       mtask.Wait(semtimer);
       i = 0;
       while (1)
              {
              mtask.Sleep(1L);
              i++;
              if (status == RUNNING)
                {
                if (i % 5 == 0)
                     {
                     InvalidateRect(hwndMainWindow, NULL, TRUE);
                     lTime = time(0) - lStart;
                     }
                }
              else
                     break;
              }
       }
}

/* The thread to actually carry out the Salvage benchmark
for a number of iterations */
VOID Big(VOID)
{
  double x;
  int i;

  while (1)
       {
       mtask.Wait(semjob);
       for (i = 0; i < nIterations; i++)
              {
              if (!fContinue)
                break;
              x = Savage(1.0);
              mtask.Preempt();
              }
       lTime = time(0) - lStart;
       if (fContinue)
              status = DONE;
       else
              status = ABORTED;
       GpfMenuGray(hwndMainWindow,ID_START,FALSE);
       GpfMenuGray(hwndMainWindow,ID_ABORT,TRUE);
       InvalidateRect(hwndMainWindow, NULL, TRUE);
       }
}

/* Used to check mark the iteration count selected by the user */

VOID SelectRep( PGPFPARMS pGpfParms)
{

  GpfMenuTick(hwndMainWindow,idCommand,FALSE);
  idCommand = pGpfParms->Command;
  GpfMenuTick(hwndMainWindow,pGpfParms->Command,TRUE);
  return;

}

/* Used to start the Salvage benchmark by signalling the thread Big */
VOID StartSalvage( PGPFPARMS pGpfParms)
{

  GpfMenuGray(hwndMainWindow, ID_ABORT,FALSE);
  GpfMenuGray(hwndMainWindow, ID_START,TRUE);
  nIterations = rep[idCommand - ID_REP10];
  fContinue = TRUE;
  time(&lStart);
  status = RUNNING;
  lTime = 0L;
  InvalidateRect(hwndMainWindow, NULL, TRUE);

  mtask.Signal(semjob);
  mtask.Signal(semtimer);

  return;

}

/* Used to abort the executing Salvage benchmark */
VOID AbortSalvage( PGPFPARMS pGpfParms)
{
  fContinue = FALSE;
  GpfMenuGray(hwndMainWindow, ID_START, FALSE);
  GpfMenuGray(hwndMainWindow,ID_ABORT,TRUE);

  return;

}

/* Used to create the Timer and Big threads */
VOID CreateThreads(VOID)
{
  /* create mutlitasking environment */
  thdtimer =mtask.CreateThread(Timer, STACKSIZE, NULL);
  thdbig =mtask.CreateThread(Big, STACKSIZE, NULL);
  semjob = mtask.CreateSem(0);
  semtimer = mtask.CreateSem(0);
  GpfMenuGray(hwndMainWindow, ID_ABORT,TRUE);
  GpfMenuTick(hwndMainWindow, ID_REP10,TRUE);
}

/* Main PeekMessage loop to replace the normal
   GetMessage loop */
VOID PeekMessageLoop(MSG * pMsg, Cschlr *pTask)
{

  BOOL fGo = TRUE;

  while (fGo)
       {
       if (pTask != NULL)
         {
         while (!PeekMessage(pMsg,NULL,NULL,NULL,PM_NOREMOVE))
           pTask->Run();
         }

       if (GetMessage(pMsg,NULL,NULL,NULL))
         {
         if ((!pMsg->hwnd) || (!IsDialogMessage
                           (GetActiveWindow(),pMsg)))
           {
           TranslateMessage(pMsg);
           DispatchMessage(pMsg);
           }

         }

       else
           fGo = FALSE;

       }
}

// End of File