home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 28 / amigaformatcd28.iso / -seriously_amiga- / programming / other / wipeout / source / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-27  |  16.9 KB  |  826 lines

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