2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
5 Desc: Basic functions for ressource tracking
10 #define ENABLE_RT 0 /* no RT inside this file */
14 #include <exec/lists.h>
15 #include <aros/system.h>
16 #include <exec/tasks.h>
17 #include <exec/ports.h>
18 #include <exec/execbase.h>
22 #include <proto/dos.h>
23 #include <proto/intuition.h>
24 #include <proto/alib.h>
28 #include <exec/memory.h>
29 #include <proto/arossupport.h>
30 #include <proto/exec.h>
32 /* iaint: Use the debugging macros from now on. */
33 #include <aros/debug.h>
35 RTData
* intRTD
= NULL
; /* Internal pointer in case no ETask is available */
36 RTDesc
const * RT_Resources
[RTT_MAX
];
38 /*****************************************************************************
49 Begin initialization of resource tracking.
68 24-12-95 digulla created
70 ******************************************************************************/
75 if ((rtd
= GetRTData ()))
77 D(bug ("RT_Init() called twice %p\n", rtd
) );
81 if (!(rtd
= AllocMem (sizeof (RTData
), MEMF_ANY
)) )
83 D(bug ("RT_Init(): No memory\n") );
89 rtd
->rtd_Version
= RT_VERSION
;
90 rtd
->rtd_StackPtr
= STACKDEPTH
;
93 /*****************************************************************************
104 End initialization of resource tracking.
123 24-12-95 digulla created
125 ******************************************************************************/
132 for (t
=0; t
<RTT_MAX
; t
++)
134 for (i
=0; i
<HASH_SIZE
; i
++)
136 NEWLIST(&rtd
->rtd_ResHash
[t
][i
]);
140 D(bug ("RT_Init(): RT up and kicking in %s mode\n"
141 , intRTD
? "internal" : "ETask"
145 /*****************************************************************************
156 Stops the resource tracking. All resources which are still allocated
157 are printed and then released.
174 Free the resources from back to front. This allows to sort the
175 resources (ie. windows on a screen are closed before the screen,
179 24-12-95 digulla created
181 ******************************************************************************/
187 if (!(rtd
= GetRTData ()) )
190 for (t
=RTT_MAX
-1; t
>=0; t
--)
192 for (i
=0; i
<HASH_SIZE
; i
++)
194 for (next
=(RTNode
*)GetHead(&rtd
->rtd_ResHash
[t
][i
]); (rt
=next
); )
196 next
= (RTNode
*)GetSucc (rt
);
198 RT_FreeResource (rtd
, t
, rt
);
204 /*****************************************************************************
215 Stops the resource tracking. All resources which are still allocated
216 are printed and then released.
233 Free the resources from back to front. This allows to sort the
234 resources (ie. windows on a screen are closed before the screen,
238 24-12-95 digulla created
240 ******************************************************************************/
245 if (!(rtd
= GetRTData ()) )
248 FreeMem (rtd
, sizeof (RTData
));
253 /*****************************************************************************
267 Adds a resource to be tracked. The arguments after
268 line depend on the type of resource to be traced:
270 RTT_ALLOCMEM: APTR memPtr,
274 rtt - Type of the resource
275 file - The file RT_IntAdd was called it
276 line - The line of the file
277 task - The task to be added
278 memPtr - Pointer to a piece of memory to be tracked
279 size - The size of the memory beginning at memPtr
295 24-12-95 digulla created
297 ******************************************************************************/
306 if (!(rtd
= GetRTData ()) )
309 if (!(rtnew
= AllocMem (GetRTSize(rtt
), MEMF_ANY
)) )
311 D(bug ("RT_IntAdd: Out of memory\n") );
319 va_start (args
, line
);
323 ret
= (*GetRTAllocFunc(rtt
))
335 AddTail ((struct List
*)&rtd
->rtd_ResHash
[rtt
][CALCHASH(HASH_BASE(rtnew
))]
336 ,(struct Node
*)rtnew
341 FreeMem (rtnew
, GetRTSize(rtt
));
347 /*****************************************************************************
362 Adds a resource to be tracked. The arguments after
363 line depend on the type of resource to be traced.
364 The resource›is marked as "must not be freed by the
368 rtt - Type of the resource
369 file - The file RT_IntAdd was called it
370 line - The line of the file
371 res - Pointer to the resouce
387 24-12-95 digulla created
389 ******************************************************************************/
396 if (!(rtd
= GetRTData ()) )
399 if (!(rtnew
= AllocMem (GetRTSize(rtt
), MEMF_ANY
|MEMF_CLEAR
)) )
401 D(bug("RT_IntAdd: Out of memory\n"));
405 rtnew
->Node
.File
= file
;
406 rtnew
->Node
.Line
= line
;
407 rtnew
->Node
.Flags
= RTNF_DONT_FREE
;
408 rtnew
->Resource
= res
;
410 va_start (args
, res
);
414 AddTail ((struct List
*)&rtd
->rtd_ResHash
[rtt
][CALCHASH(HASH_BASE(rtnew
))]
415 , (struct Node
*)rtnew
420 /*****************************************************************************
435 Checks a resource. Will print an error if the resource is not found
436 or has already been freed or if the type of the resource doesn't
437 match. The arguments after line depend on the type of resource to
440 RTT_ALLOCMEM: APTR memPtr,
444 rtt - Type of the resource
445 file - The file RT_IntCheck was called it
446 line - The line of the file
447 task - The task to be added
448 memPtr - Pointer to a piece of memory to be tracked
449 size - The size of the memory beginning at memPtr
455 All strings must be static.
466 24-12-95 digulla created
468 ******************************************************************************/
475 if (!(rtd
= GetRTData ()) )
480 if (GetRTCheckFunc(rtt
))
482 ret
= (*(GetRTCheckFunc(rtt
)))
494 ret
= (*(GetRTSearchFunc(rtt
)))
502 if (ret
!= RT_SEARCH_FOUND
)
504 ret
= (*(GetRTShowError(rtt
)))
523 /*****************************************************************************
537 Stops tracing of a resource. The arguments after
538 line depend on the type of resource to be traced.
541 rtt - Type of the resource
542 file - The file RT_IntAdd was called it
543 line - The line of the file
549 All strings must be static.
560 24-12-95 digulla created
562 ******************************************************************************/
569 if (!(rtd
= GetRTData ()) )
572 va_start (args
, line
);
574 ret
= (*(GetRTSearchFunc(rtt
)))
582 if (ret
== RT_SEARCH_FOUND
&& rt
&& !(rt
->Flags
& RTNF_DONT_FREE
))
584 ret
= (*(GetRTFreeFunc(rtt
))) (rtd
, rt
);
586 Remove ((struct Node
*)rt
);
587 FreeMem (rt
, GetRTSize(rtt
));
591 ret
= (*(GetRTShowError(rtt
)))
610 /*****************************************************************************
618 const char * function
,
623 Tells the RT that a new function is about to be entered. This is used
624 to make it easier to track an error.
627 function - name of the function to be entered
628 file - file with the call of the function
629 line - Line-number of the call
635 All strings must be static.
646 24-12-95 digulla created
648 ******************************************************************************/
652 if (!(rtd
= GetRTData ()) )
655 if (rtd
->rtd_StackPtr
== 0)
658 -- rtd
->rtd_StackPtr
;
660 rtd
->rtd_CallStack
[rtd
->rtd_StackPtr
].Function
= function
;
661 rtd
->rtd_CallStack
[rtd
->rtd_StackPtr
].File
= file
;
662 rtd
->rtd_CallStack
[rtd
->rtd_StackPtr
].Line
= line
;
666 /*****************************************************************************
677 Tells the RT that a the function has been left.
696 24-12-95 digulla created
698 ******************************************************************************/
702 if (!(rtd
= GetRTData ()) )
705 if (rtd
->rtd_StackPtr
== STACKDEPTH
)
708 rtd
->rtd_CallStack
[rtd
->rtd_StackPtr
].Function
= NULL
;
709 rtd
->rtd_CallStack
[rtd
->rtd_StackPtr
].File
= NULL
;
710 rtd
->rtd_CallStack
[rtd
->rtd_StackPtr
].Line
= 0;
712 rtd
->rtd_StackPtr
++;
716 /*****************************************************************************
727 Prints the contents of the callstack stored in the node.
730 node - The node with the callstack to be printed
746 24-12-95 digulla created
748 ******************************************************************************/
754 if (!(rtd
= GetRTData ()) )
757 for (t
=0; t
<KEEPDEPTH
&& node
->Stack
[t
].Function
; t
++)
758 D(bug((" %s (%s:%d)\n"
759 , node
->Stack
[t
].Function
760 , node
->Stack
[t
].File
761 , node
->Stack
[t
].Line
767 /*****************************************************************************
772 void RT_ShowRTStack (
778 Prints the contents of the callstack built by RT_Enter() and
798 24-12-95 digulla created
800 ******************************************************************************/
805 if (!(rtd
= GetRTData ()) )
808 for (t
=0; t
<=rtd
->rtd_StackPtr
; t
++)
810 D(bug(" %s (%s:%d)\n"
811 , rtd
->rtd_CallStack
[t
].Function
812 , rtd
->rtd_CallStack
[t
].File
813 , rtd
->rtd_CallStack
[t
].Line
816 } /* RT_ShowRTStack */
819 /*****************************************************************************
824 void RT_FreeResource (
832 Free a resource after the task that allocated it, died. Also
833 print a nasty message about this.
836 rt - The node with the resource to be freed.
850 Don't free the node or remove it from the list. This is done
854 24-12-95 digulla created
856 ******************************************************************************/
859 if (!rtd
&& !(rtd
= GetRTData ()))
862 if (!(rtnode
->Flags
& RTNF_DONT_FREE
) )
865 (void) (*(GetRTShowError(rtt
)))
877 /* free the resource */
878 (void) (*(GetRTFreeFunc(rtt
))) (rtd
, rtnode
);
881 /* Remove resource from list and free it */
882 Remove ((struct Node
*)rtnode
);
883 FreeMem (rtnode
, GetRTSize(rtt
));
885 } /* RT_FreeResource */
888 /**************************************
890 **************************************/
892 BOOL
CheckPtr (APTR ptr
, ULONG flags
)
896 (!ptr
&& !(flags
& NULL_PTR
))
897 || (((IPTR
)ptr
& 3) && (flags
& ALIGNED_PTR
))
907 BOOL
CheckArea (APTR ptr
, ULONG size
, ULONG flags
)
912 || !CheckPtr (ptr
+size
-1, flags
)
919 IPTR
RT_Search (RTData
* rtd
, int rtt
, RTNode
** rtptr
, va_list args
)
924 res
= va_arg (args
, APTR
);
926 ForeachNode (&rtd
->rtd_ResHash
[rtt
][CALCHASH(res
)], rt
)
928 if (rt
->Resource
== res
)
930 *rtptr
= (RTNode
*)rt
;
932 return RT_SEARCH_FOUND
;
936 return RT_SEARCH_NOT_FOUND
;