home *** CD-ROM | disk | FTP | other *** search
/ Aminet 18 / aminetcdnumber181997.iso / Aminet / misc / emu / AROSdev.lha / AROS / compiler / aros / rt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-27  |  11.6 KB  |  691 lines

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: rt.c,v 1.3 1997/01/27 00:17:41 ldp Exp $
  4.     $Log: rt.c,v $
  5.     Revision 1.3  1997/01/27 00:17:41  ldp
  6.     Include proto instead of clib
  7.  
  8.     Revision 1.2  1996/12/10 13:59:45  aros
  9.     Moved #include into first column to allow makedepend to see it.
  10.  
  11.     Revision 1.1  1996/08/23 17:26:44  digulla
  12.     Files with functions for RT and Purify
  13.  
  14.  
  15.     Desc:
  16.     Lang:
  17. */
  18. #define AROS_ALMOST_COMPATIBLE
  19.  
  20. #define ENABLE_RT 0    /* no RT inside this file */
  21. #include <aros/rt.h>
  22. #undef RT_Init
  23. #undef RT_Leave
  24.  
  25. #include <exec/lists.h>
  26. #include <aros/system.h>
  27. #include <exec/tasks.h>
  28. #include <exec/memory.h>
  29. #include <exec/execbase.h>
  30. #include <stdarg.h>
  31. #include <stdlib.h>
  32. #include <proto/exec.h>
  33. #include <proto/aros.h>
  34.  
  35. extern struct ExecBase * SysBase;
  36.  
  37. struct CallStack
  38. {
  39.     char * Function;
  40.     char * File;
  41.     int    Line;
  42. };
  43.  
  44. #define KEEPDEPTH   6
  45. #define RT_STACKDEPTH    256
  46.  
  47. struct RTNode
  48. {
  49.     struct Node      Node;
  50.     char       * File;
  51.     int          Line;
  52.     struct CallStack Stack[KEEPDEPTH];
  53. };
  54.  
  55. struct CallStack RT_CallStack[RT_STACKDEPTH];
  56. int         RT_StackPtr;
  57.  
  58. struct MemoryResource
  59. {
  60.     struct RTNode Node;
  61.     void    * Memory;
  62.     ULONG      Size;
  63. };
  64.  
  65. #define MAX_RESOURCES    2
  66. static struct List RT_Resources[MAX_RESOURCES];
  67. static int RT_Sizes[MAX_RESOURCES] =
  68. {
  69.     sizeof (struct MemoryResource),
  70. };
  71.  
  72. static void RT_ShowStack (struct RTNode *);
  73. static void RT_FreeResource (int rtt, struct RTNode *);
  74. static int InitWasCalled;
  75.  
  76. /* Silently global functions */
  77. void RT_ShowRTStack (void);
  78.  
  79. /*****************************************************************************
  80.  
  81.     NAME */
  82. #include <aros/rt.h>
  83.  
  84.     void RT_Init (
  85.  
  86. /*  SYNOPSIS */
  87.     void)
  88.  
  89. /*  FUNCTION
  90.     Initialize the resource tracking
  91.  
  92.     INPUTS
  93.     none
  94.  
  95.     RESULT
  96.     none
  97.  
  98.     NOTES
  99.     This function is not part of a library and may thus be called
  100.     any time.
  101.  
  102.     EXAMPLE
  103.  
  104.     BUGS
  105.  
  106.     SEE ALSO
  107.  
  108.     INTERNALS
  109.  
  110.     HISTORY
  111.     24-12-95    digulla created
  112.  
  113. ******************************************************************************/
  114. {
  115.     int t;
  116.  
  117.     for (t=0; t<MAX_RESOURCES; t++)
  118.     NEWLIST (&RT_Resources[t]);
  119.  
  120.     InitWasCalled = 1;
  121.  
  122.     FindTask(NULL)->tc_UserData = RT_ShowRTStack;
  123. } /* RT_Init */
  124.  
  125.  
  126. /*****************************************************************************
  127.  
  128.     NAME */
  129. #include <aros/rt.h>
  130.  
  131.     void RT_IntAdd (
  132.  
  133. /*  SYNOPSIS */
  134.     int    rtt,
  135.     char * file,
  136.     int    line,
  137.     ...)
  138.  
  139. /*  FUNCTION
  140.     Adds a resource to be tracked. The arguments after
  141.     line depend on the type of resource to be traced:
  142.  
  143.     RTT_MEMORY:    APTR          memPtr,
  144.             ULONG          size)
  145.  
  146.     INPUTS
  147.     rtt - Type of the resource
  148.     file - The file RT_IntAdd was called it
  149.     line - The line of the file
  150.     task - The task to be added
  151.     memPtr - Pointer to a piece of memory to be tracked
  152.     size - The size of the memory beginning at memPtr
  153.  
  154.     RESULT
  155.     none
  156.  
  157.     NOTES
  158.     This function is not part of a library and may thus be called
  159.     any time.
  160.  
  161.     EXAMPLE
  162.  
  163.     BUGS
  164.  
  165.     SEE ALSO
  166.  
  167.     INTERNALS
  168.  
  169.     HISTORY
  170.     24-12-95    digulla created
  171.  
  172. ******************************************************************************/
  173. {
  174.     va_list args;
  175.     struct RTNode * rtnew;
  176.     int t;
  177.  
  178.     if (!InitWasCalled)
  179.     return;
  180.  
  181.     if (!(rtnew = malloc (RT_Sizes[rtt])) )
  182.     {
  183.     kprintf ("RT_IntAdd: Out of memory\n");
  184.     return;
  185.     }
  186.  
  187.     rtnew->File = file;
  188.     rtnew->Line = line;
  189.  
  190.  
  191.     if (RT_StackPtr < KEEPDEPTH)
  192.     {
  193.     for (t=0; t<=RT_StackPtr; t++)
  194.     {
  195.         rtnew->Stack[t] = RT_CallStack[t];
  196.     }
  197.  
  198.     for ( ; t < KEEPDEPTH; t++)
  199.         rtnew->Stack[t].Function = NULL;
  200.     }
  201.     else
  202.     {
  203.     for (t=0; t<KEEPDEPTH; t++)
  204.     {
  205.         rtnew->Stack[t] = RT_CallStack[RT_StackPtr - (KEEPDEPTH-1) + t];
  206.     }
  207.     }
  208.  
  209.     va_start (args, line);
  210.  
  211.     switch (rtt)
  212.     {
  213.     case RTT_MEMORY: {
  214.     struct MemoryResource * rt = (struct MemoryResource *) rtnew;
  215.  
  216.     rt->Memory = va_arg (args, APTR);
  217.     rt->Size = va_arg (args, ULONG);
  218.  
  219.     break; }
  220.  
  221.     }
  222.  
  223.     va_end (args);
  224. } /* RT_IntAdd */
  225.  
  226. /*****************************************************************************
  227.  
  228.     NAME */
  229. #include <aros/rt.h>
  230.  
  231.     void RT_IntCheck (
  232.  
  233. /*  SYNOPSIS */
  234.     int    rtt,
  235.     char * file,
  236.     int    line,
  237.     ...)
  238.  
  239. /*  FUNCTION
  240.     Checks a resource. Will print an error if the resource is not found
  241.     or has already been freed or if the type of the resource doesn't
  242.     match. The arguments after line depend on the type of resource to
  243.     be traced:
  244.  
  245.     RTT_MEMORY:    APTR          memPtr,
  246.             ULONG          size)
  247.  
  248.     INPUTS
  249.     rtt - Type of the resource
  250.     file - The file RT_IntCheck was called it
  251.     line - The line of the file
  252.     task - The task to be added
  253.     memPtr - Pointer to a piece of memory to be tracked
  254.     size - The size of the memory beginning at memPtr
  255.  
  256.     RESULT
  257.     none
  258.  
  259.     NOTES
  260.     This function is not part of a library and may thus be called
  261.     any time.
  262.  
  263.     EXAMPLE
  264.  
  265.     BUGS
  266.  
  267.     SEE ALSO
  268.  
  269.     INTERNALS
  270.  
  271.     HISTORY
  272.     24-12-95    digulla created
  273.  
  274. ******************************************************************************/
  275. {
  276.     va_list args;
  277.  
  278.     if (!InitWasCalled)
  279.     return;
  280.  
  281.     va_start (args, line);
  282.  
  283.     switch (rtt)
  284.     {
  285.     case RTT_MEMORY: {
  286.     struct MemoryResource * rt;
  287.     APTR memory;
  288.     ULONG size;
  289.  
  290.     memory = va_arg (args, APTR);
  291.     size = va_arg (args, ULONG);
  292.  
  293.     for (rt=GetHead (&RT_Resources[rtt]); rt; rt=GetSucc(rt))
  294.     {
  295.         if (rt->Memory == memory)
  296.         {
  297.         if (rt->Size == size)
  298.             return;
  299.  
  300.         kprintf ("RT: Size mismatch (%ld)\n", size);
  301.         kprintf ("    MemPtr=%p Size=%ld\n", rt->Memory, rt->Size);
  302.         RT_ShowStack (&rt->Node);
  303.  
  304.         return;
  305.         }
  306.     }
  307.  
  308.     kprintf ("RT: Memory not found %p, Size=%ld\n", memory, size);
  309.     kprintf ("    %s:%d\n", file, line);
  310.     RT_ShowRTStack ();
  311.  
  312.     break; }
  313.  
  314.     }
  315.  
  316.     va_end (args);
  317. } /* RT_IntCheck */
  318.  
  319. /*****************************************************************************
  320.  
  321.     NAME */
  322. #include <aros/rt.h>
  323.  
  324.     void RT_IntFree (
  325.  
  326. /*  SYNOPSIS */
  327.     int    rtt,
  328.     char * file,
  329.     int    line,
  330.     ...)
  331.  
  332. /*  FUNCTION
  333.     Stops tracing of a resource. The arguments after
  334.     line depend on the type of resource to be traced:
  335.  
  336.     RTT_MEMORY:    APTR          memPtr,
  337.             ULONG          size)
  338.  
  339.     INPUTS
  340.     rtt - Type of the resource
  341.     file - The file RT_IntAdd was called it
  342.     line - The line of the file
  343.     task - The task to be added
  344.     memPtr - Pointer to a piece of memory to be tracked
  345.     size - The size of the memory beginning at memPtr
  346.  
  347.     RESULT
  348.     none
  349.  
  350.     NOTES
  351.     This function is not part of a library and may thus be called
  352.     any time.
  353.  
  354.     EXAMPLE
  355.  
  356.     BUGS
  357.  
  358.     SEE ALSO
  359.  
  360.     INTERNALS
  361.  
  362.     HISTORY
  363.     24-12-95    digulla created
  364.  
  365. ******************************************************************************/
  366. {
  367.     va_list args;
  368.  
  369.     if (!InitWasCalled)
  370.     return;
  371.  
  372.     va_start (args, line);
  373.  
  374.     switch (rtt)
  375.     {
  376.     case RTT_MEMORY: {
  377.     struct MemoryResource * rt;
  378.     APTR memory;
  379.     ULONG size;
  380.  
  381.     memory = va_arg (args, APTR);
  382.     size = va_arg (args, ULONG);
  383.  
  384.     for (rt=GetHead (&RT_Resources[rtt]); rt; rt=GetSucc(rt))
  385.     {
  386.         if (rt->Memory == memory)
  387.         {
  388.         if (rt->Size == size)
  389.         {
  390.             Remove ((struct Node *)rt);
  391.             free (rt);
  392.  
  393.             return;
  394.         }
  395.  
  396.         kprintf ("RT: Size mismatch (%ld)\n", size);
  397.         kprintf ("    MemPtr=%p Size=%ld\n", rt->Memory, rt->Size);
  398.         RT_ShowStack (&rt->Node);
  399.  
  400.         return;
  401.         }
  402.     }
  403.  
  404.     kprintf ("RT: Memory not found %p, Size=%ld\n", memory, size);
  405.     kprintf ("    %s:%d\n", file, line);
  406.     RT_ShowRTStack ();
  407.  
  408.     break; }
  409.  
  410.     }
  411.  
  412.     va_end (args);
  413. } /* RT_IntFree */
  414.  
  415.  
  416. /*****************************************************************************
  417.  
  418.     NAME */
  419. #include <aros/rt.h>
  420.  
  421.     void RT_IntEnter (
  422.  
  423. /*  SYNOPSIS */
  424.     char * function,
  425.     char * file,
  426.     int    line)
  427.  
  428. /*  FUNCTION
  429.     Tells the RT that a new function is about to be entered. This is used
  430.     to make it easier to track an error.
  431.  
  432.     INPUTS
  433.     function - name of the function to be entered
  434.     file - file with the call of the function
  435.     line - Line-number of the call
  436.  
  437.     RESULT
  438.     none
  439.  
  440.     NOTES
  441.     This function is not part of a library and may thus be called
  442.     any time.
  443.  
  444.     All strings must be static.
  445.  
  446.     EXAMPLE
  447.  
  448.     BUGS
  449.  
  450.     SEE ALSO
  451.  
  452.     INTERNALS
  453.  
  454.     HISTORY
  455.     24-12-95    digulla created
  456.  
  457. ******************************************************************************/
  458. {
  459.     if (!InitWasCalled)
  460.     return;
  461.  
  462.     if (RT_StackPtr == RT_STACKDEPTH)
  463.     return;
  464.  
  465.     RT_CallStack[RT_StackPtr].Function = function;
  466.     RT_CallStack[RT_StackPtr].File     = file;
  467.     RT_CallStack[RT_StackPtr].Line     = line;
  468.  
  469.     RT_StackPtr ++;
  470. } /* RT_IntEnter */
  471.  
  472.  
  473. /*****************************************************************************
  474.  
  475.     NAME */
  476. #include <aros/rt.h>
  477.  
  478.     void RT_IntLeave (
  479.  
  480. /*  SYNOPSIS */
  481.     void)
  482.  
  483. /*  FUNCTION
  484.     Tells the RT that a the function has been left.
  485.  
  486.     INPUTS
  487.     none
  488.  
  489.     RESULT
  490.     none
  491.  
  492.     NOTES
  493.     This function is not part of a library and may thus be called
  494.     any time.
  495.  
  496.     EXAMPLE
  497.  
  498.     BUGS
  499.  
  500.     SEE ALSO
  501.  
  502.     INTERNALS
  503.  
  504.     HISTORY
  505.     24-12-95    digulla created
  506.  
  507. ******************************************************************************/
  508. {
  509.     if (!InitWasCalled)
  510.     return;
  511.  
  512.     if (!RT_StackPtr)
  513.     return;
  514.  
  515.     RT_StackPtr --;
  516.  
  517.     RT_CallStack[RT_StackPtr].Function = NULL;
  518.     RT_CallStack[RT_StackPtr].File     = NULL;
  519.     RT_CallStack[RT_StackPtr].Line     = 0;
  520. } /* RT_IntLeave */
  521.  
  522.  
  523. /*****************************************************************************
  524.  
  525.     NAME */
  526. #include <aros/rt.h>
  527.  
  528.     void RT_ShowStack (
  529.  
  530. /*  SYNOPSIS */
  531.     struct RTNode * node)
  532.  
  533. /*  FUNCTION
  534.     Prints the contents of the callstack stored in the node.
  535.  
  536.     INPUTS
  537.     node - The node with the callstack to be printed
  538.  
  539.     RESULT
  540.     none
  541.  
  542.     NOTES
  543.     This function is not part of a library and may thus be called
  544.     any time.
  545.  
  546.     EXAMPLE
  547.  
  548.     BUGS
  549.  
  550.     SEE ALSO
  551.  
  552.     INTERNALS
  553.  
  554.     HISTORY
  555.     24-12-95    digulla created
  556.  
  557. ******************************************************************************/
  558. {
  559.     int t;
  560.  
  561.     if (!InitWasCalled)
  562.     return;
  563.  
  564.     for (t=0; t<KEEPDEPTH && node->Stack[t].Function; t++)
  565.     kprintf ("    %s (%s:%d)\n"
  566.         , node->Stack[t].Function
  567.         , node->Stack[t].File
  568.         , node->Stack[t].Line
  569.     );
  570. } /* RT_ShowStack */
  571.  
  572.  
  573. /*****************************************************************************
  574.  
  575.     NAME */
  576. #include <aros/rt.h>
  577.  
  578.     void RT_ShowRTStack (
  579.  
  580. /*  SYNOPSIS */
  581.     void)
  582.  
  583. /*  FUNCTION
  584.     Prints the contents of the callstack built by RT_Enter() and
  585.     RT_Leave().
  586.  
  587.     INPUTS
  588.     none
  589.  
  590.     RESULT
  591.     none
  592.  
  593.     NOTES
  594.     This function is not part of a library and may thus be called
  595.     any time.
  596.  
  597.     EXAMPLE
  598.  
  599.     BUGS
  600.  
  601.     SEE ALSO
  602.  
  603.     INTERNALS
  604.  
  605.     HISTORY
  606.     24-12-95    digulla created
  607.  
  608. ******************************************************************************/
  609. {
  610.     int t;
  611.  
  612.     if (!InitWasCalled)
  613.     return;
  614.  
  615.     for (t=0; t<=RT_StackPtr; t++)
  616.     {
  617.     kprintf ("    %s (%s:%d)\n"
  618.         , RT_CallStack[t].Function
  619.         , RT_CallStack[t].File
  620.         , RT_CallStack[t].Line
  621.     );
  622.     }
  623. } /* RT_ShowRTStack */
  624.  
  625.  
  626. /*****************************************************************************
  627.  
  628.     NAME */
  629. #include <aros/rt.h>
  630.  
  631.     void RT_FreeResource (
  632.  
  633. /*  SYNOPSIS */
  634.     int rtt,
  635.     struct RTNode * rtnode)
  636.  
  637. /*  FUNCTION
  638.     Free a resource after the task that allocated it, died. Also
  639.     print a nasty message about this.
  640.  
  641.     INPUTS
  642.     rt - The node with the resource to be freed.
  643.  
  644.     RESULT
  645.     none
  646.  
  647.     NOTES
  648.     This function is not part of a library and may thus be called
  649.     any time.
  650.  
  651.     EXAMPLE
  652.  
  653.     BUGS
  654.  
  655.     SEE ALSO
  656.  
  657.     INTERNALS
  658.     Don't free the node or remove it from the list. This is done
  659.     elsewhere.
  660.  
  661.     HISTORY
  662.     24-12-95    digulla created
  663.  
  664. ******************************************************************************/
  665. {
  666.     if (!InitWasCalled)
  667.     return;
  668.  
  669.     switch (rtt)
  670.     {
  671.     case RTT_MEMORY: {
  672.     struct MemoryResource * rt = (struct MemoryResource *)rtnode;
  673.  
  674.     /* Show the problem */
  675.     kprintf ("RT: Freeing memory %p, Size=%ld, allocated at\n"
  676.         , rt->Memory
  677.         , rt->Size
  678.     );
  679.     RT_ShowStack (rtnode);
  680.  
  681.     /* free the resource */
  682.     FreeMem (rt->Memory, rt->Size);
  683.  
  684.     break; }
  685.  
  686.     }
  687.  
  688. } /* RT_FreeResource */
  689.  
  690.  
  691.