home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 4 / AACD04.ISO / AACD / Programming / Wipeout / source / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-01-20  |  17.4 KB  |  864 lines

  1. /*
  2.  * $Id: main.c 1.20 1998/05/31 10:06:13 olsen Exp olsen $
  3.  *
  4.  * :ts=4
  5.  *
  6.  * Wipeout -- Traces and munges memory and detects memory trashing
  7.  *
  8.  * Written by Olaf `Olsen' Barthel <olsen@sourcery.han.de>
  9.  * Public Domain
  10.  */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "global.h"
  14. #endif    /* _GLOBAL_H */
  15.  
  16. /******************************************************************************/
  17.  
  18. #include "Wipeout_rev.h"
  19.  
  20. /******************************************************************************/
  21.  
  22. const STRPTR VersTag = VERSTAG;
  23.  
  24. /******************************************************************************/
  25.  
  26. STATIC const STRPTR Separator = "======================================="
  27.                                 "=======================================";
  28.  
  29. /******************************************************************************/
  30.  
  31. STATIC struct WipeoutSemaphore *    WipeoutSemaphore;
  32. STATIC BOOL                            WipeoutSemaphoreCreated;
  33.  
  34. /******************************************************************************/
  35.  
  36. STATIC BOOL ShowBannerMessage = TRUE;
  37.  
  38. /******************************************************************************/
  39.  
  40. STATIC BYTE TimerSignal;
  41.  
  42. /******************************************************************************/
  43.  
  44. STATIC struct WipeoutSemaphore *
  45. FindWipeoutSemaphore(VOID)
  46. {
  47.     struct WipeoutSemaphore * ws;
  48.  
  49.     ws = (struct WipeoutSemaphore *)FindSemaphore(WIPEOUTSEMAPHORENAME);
  50.  
  51.     return(ws);
  52. }
  53.  
  54. STATIC VOID
  55. DeleteWipeoutSemaphore(struct WipeoutSemaphore * ws)
  56. {
  57.     if(ws != NULL)
  58.     {
  59.         /* remove the semaphore from the public list */
  60.         RemSemaphore((struct SignalSemaphore *)ws);
  61.  
  62.         /* gain ownership over it */
  63.         ObtainSemaphore((struct SignalSemaphore *)ws);
  64.         ReleaseSemaphore((struct SignalSemaphore *)ws);
  65.  
  66.         /* and release it */
  67.         FreeMem(ws,sizeof(*ws));
  68.     }
  69. }
  70.  
  71. STATIC struct WipeoutSemaphore *
  72. CreateWipeoutSemaphore(VOID)
  73. {
  74.     struct WipeoutSemaphore * ws;
  75.  
  76.     ws = AllocMem(sizeof(*ws),MEMF_ANY|MEMF_PUBLIC|MEMF_CLEAR);
  77.     if(ws != NULL)
  78.     {
  79.         /* fill in name and priority; AddSemaphore() will take
  80.          * care of the rest
  81.           */
  82.         ws->ws_SignalSemaphore.ss_Link.ln_Name    = ws->ws_SemaphoreName;
  83.         ws->ws_SignalSemaphore.ss_Link.ln_Pri    = 1;
  84.  
  85.         strcpy(ws->ws_SemaphoreName,WIPEOUTSEMAPHORENAME);
  86.  
  87.         /* for compatibility checking, if the semaphore
  88.          * needs to grow
  89.          */
  90.         ws->ws_Version = WIPEOUTSEMAPHOREVERSION;
  91.  
  92.         /* fill in references to changeable parameters */
  93.         ws->ws_IsActive            = &IsActive;
  94.         ws->ws_ShowFail            = &ShowFail;
  95.         ws->ws_WaitAfterHit        = &WaitAfterHit;
  96.         ws->ws_NameTag            = &NameTag;
  97.         ws->ws_NameTag            = &NameTag;
  98.         ws->ws_CheckConsistency    = &CheckConsistency;
  99.         ws->ws_ARegCheck        = &ARegCheck;
  100.         ws->ws_DRegCheck        = &DRegCheck;
  101.         ws->ws_StackCheck        = &StackCheck;
  102.         ws->ws_StackLines        = &StackLines;
  103.         ws->ws_CheckDelay        = &CheckDelay;
  104.         ws->ws_WipeoutTask        = FindTask(NULL);
  105.         ws->ws_WakeupMask        = (1UL << WakeupSignal);
  106.  
  107.         /* and finally make the semaphore public */
  108.         AddSemaphore((struct SignalSemaphore *)ws);
  109.     }
  110.  
  111.     return(ws);
  112. }
  113.  
  114. /******************************************************************************/
  115.  
  116. STATIC LONG
  117. SendWipeoutCmd(LONG command,APTR parameter)
  118. {
  119.     WipeoutSemaphore->ws_Client        = FindTask(NULL);
  120.     WipeoutSemaphore->ws_Command    = command;
  121.     WipeoutSemaphore->ws_Parameter    = parameter;
  122.     WipeoutSemaphore->ws_Error        = OK;
  123.  
  124.     /* wake up the wipeout semaphore owner and exchange
  125.      * data or information with it
  126.      */
  127.     SetSignal(0,SIG_Handshake);
  128.     Signal(WipeoutSemaphore->ws_WipeoutTask,WipeoutSemaphore->ws_WakeupMask);
  129.     Wait(SIG_Handshake);
  130.  
  131.     return(WipeoutSemaphore->ws_Error);
  132. }
  133.  
  134. /******************************************************************************/
  135.  
  136. STATIC VOID
  137. Cleanup(VOID)
  138. {
  139.     /* shut down the timer */
  140.     DeleteTimer();
  141.  
  142.     /* dispose of the semaphore */
  143.     if(WipeoutSemaphoreCreated)
  144.     {
  145.         DeleteWipeoutSemaphore(WipeoutSemaphore);
  146.         WipeoutSemaphore = NULL;
  147.     }
  148.  
  149.     /* release the semaphore */
  150.     if(WipeoutSemaphore != NULL)
  151.     {
  152.         ReleaseSemaphore((struct SignalSemaphore *)WipeoutSemaphore);
  153.         WipeoutSemaphore = NULL;
  154.     }
  155.  
  156.     /* clear the allocation filters */
  157.     ClearFilterList();
  158.  
  159.     /* get rid of the wakeup signal */
  160.     if(WakeupSignal != -1)
  161.     {
  162.         FreeSignal(WakeupSignal);
  163.         WakeupSignal = -1;
  164.     }
  165.  
  166.     /* close utility.library, if this is necessary */
  167.     #if !defined(__SASC) || defined(_M68020)
  168.     {
  169.         if(UtilityBase != NULL)
  170.         {
  171.             CloseLibrary(UtilityBase);
  172.             UtilityBase = NULL;
  173.         }
  174.     }
  175.     #endif
  176. }
  177.  
  178. STATIC BOOL
  179. Setup(VOID)
  180. {
  181.     LONG error = OK;
  182.     int i;
  183.  
  184.     WakeupSignal = -1;
  185.     InitFilterList();
  186.  
  187.     /* Kickstart 2.04 or higher required */
  188.     if(SysBase->LibNode.lib_Version < 37)
  189.     {
  190.         const STRPTR message = "This program requires Kickstart 2.04 or better.\n";
  191.  
  192.         Write(Output(),message,strlen(message));
  193.         return(FAILURE);
  194.     }
  195.  
  196.     /* determine the program name */
  197.     StrcpyN(sizeof(ProgramName),ProgramName,VERS);
  198.  
  199.     for(i = strlen(ProgramName) - 1 ; i >= 0 ; i--)
  200.     {
  201.         if(ProgramName[i] == ' ')
  202.         {
  203.             ProgramName[i] = '\0';
  204.             break;
  205.         }
  206.     }
  207.  
  208.     /* open utility.library, if this is necessary */
  209.     #if !defined(__SASC) || defined(_M68020)
  210.     {
  211.         UtilityBase = OpenLibrary("utility.library",37);
  212.         if(UtilityBase == NULL)
  213.         {
  214.             Printf("%s: Could not open utility.library V37.\n",ProgramName);
  215.             return(FAILURE);
  216.         }
  217.     }
  218.     #endif
  219.  
  220.     /* allocate the timer data */
  221.     TimerSignal = CreateTimer();
  222.     if(TimerSignal == -1)
  223.     {
  224.         Printf("%s: Could not create timer.\n",ProgramName);
  225.         return(FAILURE);
  226.     }
  227.  
  228.     /* allocate the wakeup signal */
  229.     WakeupSignal = AllocSignal(-1);
  230.     if(WakeupSignal == -1)
  231.     {
  232.         Printf("%s: Could not allocate wakeup signal.\n",ProgramName);
  233.         return(FAILURE);
  234.     }
  235.  
  236.     /* establish default options */
  237.     PreWallSize        = 32;
  238.     PostWallSize    = 32;
  239.     IsActive        = TRUE;
  240.     StackLines        = 2;
  241.  
  242.     Forbid();
  243.  
  244.     /* try to find the global wipeout semaphore */
  245.     WipeoutSemaphore = FindWipeoutSemaphore();
  246.     if(WipeoutSemaphore == NULL)
  247.     {
  248.         /* it does not exist yet; create it */
  249.         WipeoutSemaphore = CreateWipeoutSemaphore();
  250.         if(WipeoutSemaphore != NULL)
  251.         {
  252.             WipeoutSemaphoreCreated = TRUE;
  253.         }
  254.         else
  255.         {
  256.             error = ERROR_NO_FREE_STORE;
  257.         }
  258.     }
  259.     else
  260.     {
  261.         /* obtain ownership of the semaphore */
  262.         ObtainSemaphore((struct SignalSemaphore *)WipeoutSemaphore);
  263.     }
  264.  
  265.     Permit();
  266.  
  267.     if(error == OK)
  268.     {
  269.         struct RDArgs * rda;
  270.  
  271.         /* these are the command line parameters, later
  272.          * filled in by ReadArgs() below
  273.          */
  274.         struct
  275.         {
  276.             /* the following options control the startup defaults
  277.              * and cannot be changed by subsequent invocations
  278.              * of Wipeout
  279.              */
  280.             NUMBER    PreSize;
  281.             NUMBER    PostSize;
  282.             KEY        FillChar;
  283.             SWITCH    Parallel;
  284.             SWITCH    NoBanner;
  285.  
  286.             /* the following options can be changed at run-time */
  287.             SWITCH    Remunge;
  288.             SWITCH    Check;
  289.             SWITCH    Mark;
  290.             SWITCH    Unmark;
  291.             SWITCH    ShowUnmarked;
  292.             KEY        Name;
  293.             SWITCH    NameTag;
  294.             SWITCH    NoNameTag;
  295.             SWITCH    Active;
  296.             SWITCH    Inactive;
  297.             SWITCH    Wait;
  298.             SWITCH    NoWait;
  299.             SWITCH    ConsistenceCheck;
  300.             SWITCH    NoConsistenceCheck;
  301.             SWITCH    Reuse;
  302.             SWITCH    NoReuse;
  303.             SWITCH    ShowFail;
  304.             SWITCH    NoShowFail;
  305.             SWITCH    ARegCheck;
  306.             SWITCH    NoARegCheck;
  307.             SWITCH    DRegCheck;
  308.             SWITCH    NoDRegCheck;
  309.             SWITCH    StackCheck;
  310.             SWITCH    NoStackCheck;
  311.             NUMBER    StackLines;
  312.             NUMBER    CheckDelay;
  313.         } params;
  314.     
  315.         /* this is the command template, as required by ReadArgs() below;
  316.          * its contents must match the "params" data structure above
  317.          */
  318.         const STRPTR cmdTemplate =
  319.             "PRESIZE/K/N,"
  320.             "POSTSIZE/K/N,"
  321.             "FILLCHAR/K,"
  322.             "PARALLEL/S,"
  323.             "QUIET=NOBANNER/S,"
  324.             "REMUNGE=REMUNG/S,"
  325.             "CHECK/S,"
  326.             "MARK/S,"
  327.             "UNMARK/S,"
  328.             "SHOWUNMARKED/S,"
  329.             "NAME=TASK/K,"
  330.             "NAMETAG/S,"
  331.             "NONAMETAG/S,"
  332.             "ACTIVE=ENABLE/S,"
  333.             "INACTIVE=DISABLE/S,"
  334.             "WAIT/S,"
  335.             "NOWAIT/S,"
  336.             "CONSISTENCECHECK/S,"
  337.             "NOCONSISTENCECHECK/S,"
  338.             "REUSE/S,"
  339.             "NOREUSE/S,"
  340.             "SHOWFAIL/S,"
  341.             "NOSHOWFAIL/S,"
  342.             "AREGCHECK/S,"
  343.             "NOAREGCHECK/S,"
  344.             "DREGCHECK/S,"
  345.             "NODREGCHECK/S,"
  346.             "STACKCHECK/S,"
  347.             "NOSTACKCHECK/S,"
  348.             "STACKLINES/K/N,"
  349.             "CHECKDELAY/K/N";
  350.  
  351.         memset(¶ms,0,sizeof(params));
  352.  
  353.         /* read the command line parameters */
  354.         rda = ReadArgs((STRPTR)cmdTemplate,(LONG *)¶ms,NULL);
  355.         if(rda != NULL)
  356.         {
  357.             struct WipeoutSemaphore * ws = WipeoutSemaphore;
  358.  
  359.             /* set the pre-wall allocation size */
  360.             if(params.PreSize != NULL)
  361.             {
  362.                 LONG value;
  363.  
  364.                 value = ((*params.PreSize) + 3) & ~3;
  365.                 if(value < 4)
  366.                     value = 4;
  367.                 else if (value > 65535)
  368.                     value = 65535;
  369.  
  370.                 PreWallSize = value;
  371.             }
  372.  
  373.             /* set the post-wall allocation size */
  374.             if(params.PostSize != NULL)
  375.             {
  376.                 LONG value;
  377.  
  378.                 value = ((*params.PostSize) + 3) & ~3;
  379.                 if(value < 4)
  380.                     value = 4;
  381.                 else if (value > 65535)
  382.                     value = 65535;
  383.  
  384.                 PostWallSize = value;
  385.             }
  386.  
  387.             /* use a special fill character? */
  388.             if(params.FillChar != NULL)
  389.             {
  390.                 LONG number;
  391.  
  392.                 /* this can either be a decimal or a
  393.                  * hexadecimal number; the latter is
  394.                  * indicated by a preceding "$" or "0x"
  395.                  */
  396.                 if(DecodeNumber(params.FillChar,&number))
  397.                 {
  398.                     if(0 <= number && number <= 255)
  399.                     {
  400.                         SetFillChar(number);
  401.                     }
  402.                     else
  403.                     {
  404.                         error = ERROR_BAD_NUMBER;
  405.                     }
  406.                 }
  407.                 else
  408.                 {
  409.                     error = ERROR_BAD_NUMBER;
  410.                 }
  411.             }
  412.  
  413.             /* enable parallel port output? */
  414.             if(params.Parallel)
  415.             {
  416.                 ChooseParallelOutput();
  417.             }
  418.  
  419.             /* do not show the banner message? */
  420.             if(params.NoBanner)
  421.             {
  422.                 ShowBannerMessage = FALSE;
  423.             }
  424.  
  425.             /* remunge memory? */
  426.             if(params.Remunge)
  427.             {
  428.                 /* tell the semaphore owner to munge the memory */
  429.                 if(NO WipeoutSemaphoreCreated)
  430.                 {
  431.                     SendWipeoutCmd(WIPEOUTCMD_Remunge,NULL);
  432.                 }
  433.             }
  434.  
  435.             /* trigger a memory check? */
  436.             if(params.Check)
  437.             {
  438.                 Signal(ws->ws_WipeoutTask,SIG_Check);
  439.             }
  440.  
  441.             /* mark all allocations? */
  442.             if(params.Mark)
  443.             {
  444.                 /* tell the semaphore owner to mark the allocations */
  445.                 if(NO WipeoutSemaphoreCreated)
  446.                 {
  447.                     SendWipeoutCmd(WIPEOUTCMD_Mark,NULL);
  448.                 }
  449.             }
  450.  
  451.             /* clear all allocation marks? */
  452.             if(params.Unmark)
  453.             {
  454.                 /* tell the semaphore owner to clear the marks */
  455.                 if(NO WipeoutSemaphoreCreated)
  456.                 {
  457.                     SendWipeoutCmd(WIPEOUTCMD_Unmark,NULL);
  458.                 }
  459.             }
  460.  
  461.             /* show all unmarked allocations? */
  462.             if(params.ShowUnmarked)
  463.             {
  464.                 /* tell the semaphore owner to clear the marks */
  465.                 if(NO WipeoutSemaphoreCreated)
  466.                 {
  467.                     SendWipeoutCmd(WIPEOUTCMD_ShowUnmarked,NULL);
  468.                 }
  469.             }
  470.  
  471.             /* put together a list of tasks to filter out
  472.              * when making memory allocations?
  473.              */
  474.             if(params.Name != NULL)
  475.             {
  476.                 if(WipeoutSemaphoreCreated)
  477.                 {
  478.                     /* we created the semaphore, so we can
  479.                      * fill in the filter lists all by
  480.                      * ourselves.
  481.                      */
  482.                     if(CANNOT UpdateFilter(params.Name))
  483.                         error = ERROR_NO_FREE_STORE;
  484.                 }
  485.                 else
  486.                 {
  487.                     /* we did not create the semaphore,
  488.                      * so we will have to tell the semaphore
  489.                      * owner to update the filter lists.
  490.                      */
  491.                     error = SendWipeoutCmd(WIPEOUTCMD_UpdateFilterList,params.Name);
  492.                 }
  493.             }
  494.  
  495.             if(params.NameTag)
  496.             {
  497.                 (*ws->ws_NameTag) = TRUE;
  498.             }
  499.  
  500.             if(params.NoNameTag)
  501.             {
  502.                 (*ws->ws_NameTag) = FALSE;
  503.             }
  504.  
  505.             /* enable wipeout? */
  506.             if(params.Active)
  507.             {
  508.                 Signal(ws->ws_WipeoutTask,SIG_Enable);
  509.             }
  510.  
  511.             /* disable wipeout? */
  512.             if(params.Inactive)
  513.             {
  514.                 Signal(ws->ws_WipeoutTask,SIG_Disable);
  515.             }
  516.  
  517.             if(params.Wait)
  518.             {
  519.                 (*ws->ws_WaitAfterHit) = TRUE;
  520.             }
  521.  
  522.             if(params.NoWait)
  523.             {
  524.                 (*ws->ws_WaitAfterHit) = FALSE;
  525.             }
  526.  
  527.             if(params.ConsistenceCheck)
  528.             {
  529.                 (*ws->ws_CheckConsistency) = TRUE;
  530.             }
  531.  
  532.             if(params.NoConsistenceCheck)
  533.             {
  534.                 (*ws->ws_CheckConsistency) = FALSE;
  535.             }
  536.  
  537.             if(params.Reuse)
  538.             {
  539.                 (*ws->ws_NoReuse) = FALSE;
  540.             }
  541.  
  542.             if(params.NoReuse)
  543.             {
  544.                 (*ws->ws_NoReuse) = TRUE;
  545.             }
  546.  
  547.             if(params.ShowFail)
  548.             {
  549.                 (*ws->ws_ShowFail) = TRUE;
  550.             }
  551.  
  552.             if(params.NoShowFail)
  553.             {
  554.                 (*ws->ws_ShowFail) = FALSE;
  555.             }
  556.  
  557.             if(params.ARegCheck)
  558.             {
  559.                 (*ws->ws_ARegCheck) = TRUE;
  560.             }
  561.  
  562.             if(params.NoARegCheck)
  563.             {
  564.                 (*ws->ws_ARegCheck) = FALSE;
  565.             }
  566.  
  567.             if(params.DRegCheck)
  568.             {
  569.                 (*ws->ws_DRegCheck) = TRUE;
  570.             }
  571.  
  572.             if(params.NoDRegCheck)
  573.             {
  574.                 (*ws->ws_DRegCheck) = FALSE;
  575.             }
  576.  
  577.             if(params.StackCheck)
  578.             {
  579.                 (*ws->ws_StackCheck) = TRUE;
  580.             }
  581.  
  582.             if(params.NoStackCheck)
  583.             {
  584.                 (*ws->ws_StackCheck) = FALSE;
  585.             }
  586.  
  587.             if(params.StackLines != NULL)
  588.             {
  589.                 LONG value;
  590.  
  591.                 value = (*params.StackLines);
  592.                 if(value < 0)
  593.                     value = 0;
  594.  
  595.                 (*ws->ws_StackLines) = value;
  596.             }
  597.  
  598.             /* set or update the automatic check delay? */
  599.             if(params.CheckDelay != NULL)
  600.             {
  601.                 LONG value;
  602.  
  603.                 value = (*params.CheckDelay);
  604.                 if(value < 0)
  605.                     value = 0;
  606.  
  607.                 CheckDelay = value;
  608.  
  609.                 /* notify the semaphore owner of the
  610.                  * new check delay; this will automatically
  611.                  * trigger a new memory check
  612.                  */
  613.                 if(NO WipeoutSemaphoreCreated)
  614.                 {
  615.                     error = SendWipeoutCmd(WIPEOUTCMD_NewCheckDelay,(APTR)CheckDelay);
  616.                 }
  617.             }
  618.  
  619.             FreeArgs(rda);
  620.         }
  621.         else
  622.         {
  623.             error = IoErr();
  624.         }
  625.     }
  626.  
  627.     if(error == OK)
  628.     {
  629.         /* set up the tracking lists */
  630.         SetupAllocationList();
  631.         SetupPoolList();
  632.  
  633.         return(SUCCESS);
  634.     }
  635.     else
  636.     {
  637.         PrintFault(error,ProgramName);
  638.  
  639.         return(FAILURE);
  640.     }
  641. }
  642.  
  643. /******************************************************************************/
  644.  
  645. int
  646. main(
  647.     int        argc,
  648.     char **    argv)
  649. {
  650.     int result = RETURN_FAIL;
  651.  
  652.     /* set up all the data we need */
  653.     if(Setup())
  654.     {
  655.         result = RETURN_OK;
  656.  
  657.         /* are we the owner of the semaphore? if
  658.          * so, do something useful
  659.          */
  660.         if(WipeoutSemaphoreCreated)
  661.         {
  662.             ULONG signalsReceived;
  663.             ULONG sigWakeup = (1UL<<WakeupSignal);
  664.             ULONG sigTimer = (1UL<<TimerSignal);
  665.     
  666.             /* munge all free memory */
  667.             if(ShowBannerMessage)
  668.             {
  669.                 DPrintf("%s -- Traces and munges memory and detects memory trashing\n",ProgramName);
  670.                 DPrintf("Written by Olaf `Olsen' Barthel <olsen@sourcery.han.de>\n");
  671.                 DPrintf("Public Domain\n\n");
  672.  
  673.                 DPrintf("Munging memory... ");
  674.             }
  675.  
  676.             BeginMemMung();
  677.  
  678.             if(ShowBannerMessage)
  679.             {
  680.                 struct timeval tv;
  681.  
  682.                 Forbid();
  683.                 GetSysTime(&tv);
  684.                 ConvertTimeAndDate(&tv,GlobalDateTimeBuffer);
  685.                 DPrintf("done (%s).\n",GlobalDateTimeBuffer);
  686.                 Permit();
  687.             }
  688.     
  689.             /* plant the monitoring patches */
  690.             InstallPatches();
  691.  
  692.             /* if we are to check the memory list periodically,
  693.              * start the timer now
  694.              */
  695.             if(CheckDelay > 0)
  696.             {
  697.                 StartTimer(CheckDelay / 10,(CheckDelay % 10) * (MILLION / 10));
  698.             }
  699.     
  700.             while(TRUE)
  701.             {
  702.                 /* wait for something to happen */
  703.                 signalsReceived = Wait(SIG_Check | SIG_Disable | SIG_Enable | sigWakeup | sigTimer);
  704.  
  705.                 /* received a command? */
  706.                 if(FLAG_IS_SET(signalsReceived,sigWakeup))
  707.                 {
  708.                     APTR parameter = WipeoutSemaphore->ws_Parameter;
  709.                     LONG error = OK;
  710.  
  711.                     /* what are we to do now? */
  712.                     switch(WipeoutSemaphore->ws_Command)
  713.                     {
  714.                         /* update the filter list? */
  715.                         case WIPEOUTCMD_UpdateFilterList:
  716.  
  717.                             if(CANNOT UpdateFilter((STRPTR)parameter))
  718.                                 error = ERROR_NO_FREE_STORE;
  719.  
  720.                             break;
  721.  
  722.                         /* change the check timer delay? */
  723.                         case WIPEOUTCMD_NewCheckDelay:
  724.  
  725.                             CheckDelay = (LONG)parameter;
  726.  
  727.                             /* re-check the check timer delay */
  728.                             signalsReceived |= sigTimer;
  729.                             break;
  730.  
  731.                         /* remunge unallocated memory? */
  732.                         case WIPEOUTCMD_Remunge:
  733.  
  734.                             DPrintf("Remunging memory... ");
  735.                             BeginMemMung();
  736.                             DPrintf("done.\n");
  737.  
  738.                             break;
  739.  
  740.                         /* mark all "current" memory allocations? */
  741.                         case WIPEOUTCMD_Mark:
  742.  
  743.                             DPrintf("Marking memory... ");
  744.                             ChangeMemoryMarks(TRUE);
  745.                             ChangePuddleMarks(TRUE);
  746.                             DPrintf("done.\n");
  747.                             break;
  748.  
  749.                         /* clear all memory marks? */
  750.                         case WIPEOUTCMD_Unmark:
  751.  
  752.                             DPrintf("Clearing memory marks... ");
  753.                             ChangeMemoryMarks(FALSE);
  754.                             ChangePuddleMarks(FALSE);
  755.                             DPrintf("done.\n");
  756.                             break;
  757.  
  758.                         /* show all memory marks? */
  759.                         case WIPEOUTCMD_ShowUnmarked:
  760.  
  761.                             DPrintf("%s\nShowing all unmarked memory allocations\n",Separator);
  762.                             ShowUnmarkedMemory();
  763.                             ShowUnmarkedPools();
  764.                             DPrintf("%s\n\n",Separator);
  765.                             break;
  766.                     }
  767.     
  768.                     /* let the client task go */
  769.                     WipeoutSemaphore->ws_Error = error;
  770.                     Signal(WipeoutSemaphore->ws_Client,SIG_Handshake);
  771.                 }
  772.     
  773.                 /* start or stop the timer, depending on the
  774.                  * check delay length
  775.                  */
  776.                 if(FLAG_IS_SET(signalsReceived,sigTimer))
  777.                 {
  778.                     if(CheckDelay > 0)
  779.                     {
  780.                         StartTimer(CheckDelay / 10,(CheckDelay % 10) * (MILLION / 10));
  781.  
  782.                         signalsReceived |= SIG_Check;
  783.                     }
  784.                     else
  785.                     {
  786.                         StopTimer();
  787.                     }
  788.                 }
  789.  
  790.                 /* check all memory allocations */
  791.                 if(FLAG_IS_SET(signalsReceived,SIG_Check))
  792.                 {
  793.                     struct timeval tv;
  794.  
  795.                     Forbid();
  796.  
  797.                     GetSysTime(&tv);
  798.                     ConvertTimeAndDate(&tv,GlobalDateTimeBuffer);
  799.  
  800.                     DPrintf("%s\nChecking all memory allocations (%s)\n%s\n",
  801.                         Separator,GlobalDateTimeBuffer,Separator);
  802.  
  803.                     CheckAllocatedMemory();
  804.                     CheckPools();
  805.                     CheckFilter();
  806.  
  807.                     DPrintf("%s\n\n",Separator);
  808.  
  809.                     Permit();
  810.                 }
  811.     
  812.                 /* stop monitoring memory allocations */
  813.                 if(FLAG_IS_SET(signalsReceived,SIG_Disable))
  814.                 {
  815.                     if(IsActive)
  816.                     {
  817.                         struct timeval tv;
  818.     
  819.                         Forbid();
  820.     
  821.                         GetSysTime(&tv);
  822.                         ConvertTimeAndDate(&tv,GlobalDateTimeBuffer);
  823.     
  824.                         DPrintf("%s\n%s deactivated (%s)\n%s\n",
  825.                             Separator,ProgramName,GlobalDateTimeBuffer,Separator);
  826.     
  827.                         IsActive = FALSE;
  828.     
  829.                         Permit();
  830.                     }
  831.                 }
  832.     
  833.                 /* restart monitoring memory allocations */
  834.                 if(FLAG_IS_SET(signalsReceived,SIG_Enable))
  835.                 {
  836.                     if(NOT IsActive)
  837.                     {
  838.                         struct timeval tv;
  839.  
  840.                         Forbid();
  841.  
  842.                         GetSysTime(&tv);
  843.                         ConvertTimeAndDate(&tv,GlobalDateTimeBuffer);
  844.  
  845.                         DPrintf("%s\n%s activated (%s)\n%s\n",
  846.                             Separator,ProgramName,GlobalDateTimeBuffer,Separator);
  847.  
  848.                         IsActive = TRUE;
  849.  
  850.                         Permit();
  851.                     }
  852.                 }
  853.             }
  854.         }
  855.     }
  856.  
  857.     /* note that we never arrive here if we are the owner
  858.      * of the wipeout semaphore
  859.      */
  860.     Cleanup();
  861.  
  862.     return(result);
  863. }
  864.