New bitmap method SetRGBConversionFunction which can be used to
[tangerine.git] / compiler / arossupport / rt.c
blob851ffe40f3e9cfa1fab611d04299a40753c8940d
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Basic functions for ressource tracking
6 Lang: english
7 */
8 #include "rt.h"
9 #if 0
10 #define ENABLE_RT 0 /* no RT inside this file */
11 #define RT_INTERNAL 1
12 #include <aros/rt.h>
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>
19 #include <stdarg.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <proto/dos.h>
23 #include <proto/intuition.h>
24 #include <proto/alib.h>
25 #include "etask.h"
26 #endif
27 #include <string.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 /*****************************************************************************
40 NAME */
41 #include <aros/rt.h>
43 void RT_IntInitB (
45 /* SYNOPSIS */
46 void)
48 /* FUNCTION
49 Begin initialization of resource tracking.
51 INPUTS
52 none
54 RESULT
55 none
57 NOTES
59 EXAMPLE
61 BUGS
63 SEE ALSO
65 INTERNALS
67 HISTORY
68 24-12-95 digulla created
70 ******************************************************************************/
72 AROS_GET_SYSBASE_OK
73 RTData * rtd;
75 if ((rtd = GetRTData ()))
77 D(bug ("RT_Init() called twice %p\n", rtd) );
78 return;
81 if (!(rtd = AllocMem (sizeof (RTData), MEMF_ANY)) )
83 D(bug ("RT_Init(): No memory\n") );
84 return;
87 SetRTData (rtd);
89 rtd->rtd_Version = RT_VERSION;
90 rtd->rtd_StackPtr = STACKDEPTH;
91 } /* RT_IntInitB */
93 /*****************************************************************************
95 NAME */
96 #include <aros/rt.h>
98 void RT_IntInitE (
100 /* SYNOPSIS */
101 void)
103 /* FUNCTION
104 End initialization of resource tracking.
106 INPUTS
107 none
109 RESULT
110 none
112 NOTES
114 EXAMPLE
116 BUGS
118 SEE ALSO
120 INTERNALS
122 HISTORY
123 24-12-95 digulla created
125 ******************************************************************************/
127 RTData * rtd;
128 int t, i;
130 rtd = GetRTData ();
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"
142 ) );
143 } /* RT_IntInitE */
145 /*****************************************************************************
147 NAME */
148 #include <aros/rt.h>
150 void RT_IntExitB (
152 /* SYNOPSIS */
153 void)
155 /* FUNCTION
156 Stops the resource tracking. All resources which are still allocated
157 are printed and then released.
159 INPUTS
160 none
162 RESULT
163 none
165 NOTES
167 EXAMPLE
169 BUGS
171 SEE ALSO
173 INTERNALS
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,
176 etc).
178 HISTORY
179 24-12-95 digulla created
181 ******************************************************************************/
183 RTData * rtd;
184 RTNode * rt, * next;
185 int t, i;
187 if (!(rtd = GetRTData ()) )
188 return;
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);
202 } /* RT_IntExitB */
204 /*****************************************************************************
206 NAME */
207 #include <aros/rt.h>
209 void RT_IntExitE (
211 /* SYNOPSIS */
212 void)
214 /* FUNCTION
215 Stops the resource tracking. All resources which are still allocated
216 are printed and then released.
218 INPUTS
219 none
221 RESULT
222 none
224 NOTES
226 EXAMPLE
228 BUGS
230 SEE ALSO
232 INTERNALS
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,
235 etc).
237 HISTORY
238 24-12-95 digulla created
240 ******************************************************************************/
242 AROS_GET_SYSBASE_OK
243 RTData * rtd;
245 if (!(rtd = GetRTData ()) )
246 return;
248 FreeMem (rtd, sizeof (RTData));
250 SetRTData (NULL);
251 } /* RT_IntExitE */
253 /*****************************************************************************
255 NAME */
256 #include <aros/rt.h>
258 IPTR RT_IntAdd (
260 /* SYNOPSIS */
261 int rtt,
262 const char * file,
263 int line,
264 ...)
266 /* FUNCTION
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,
271 ULONG size)
273 INPUTS
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
281 RESULT
282 none
284 NOTES
286 EXAMPLE
288 BUGS
290 SEE ALSO
292 INTERNALS
294 HISTORY
295 24-12-95 digulla created
297 ******************************************************************************/
299 AROS_GET_SYSBASE_OK
300 RTData * rtd;
301 IPTR ret;
302 va_list args;
303 RTNode * rtnew;
304 BOOL success;
306 if (!(rtd = GetRTData ()) )
307 return FALSE;
309 if (!(rtnew = AllocMem (GetRTSize(rtt), MEMF_ANY)) )
311 D(bug ("RT_IntAdd: Out of memory\n") );
312 return FALSE;
315 rtnew->File = file;
316 rtnew->Line = line;
317 rtnew->Flags = 0;
319 va_start (args, line);
321 success = FALSE;
323 ret = (*GetRTAllocFunc(rtt))
325 rtd,
326 rtnew,
327 args,
328 &success
331 va_end (args);
333 if (success)
335 AddTail ((struct List *)&rtd->rtd_ResHash[rtt][CALCHASH(HASH_BASE(rtnew))]
336 ,(struct Node *)rtnew
339 else
341 FreeMem (rtnew, GetRTSize(rtt));
344 return ret;
345 } /* RT_IntAdd */
347 /*****************************************************************************
349 NAME */
350 #include <aros/rt.h>
352 void RT_IntTrack (
354 /* SYNOPSIS */
355 int rtt,
356 const char * file,
357 int line,
358 APTR res,
359 ...)
361 /* FUNCTION
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
365 user".
367 INPUTS
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
373 RESULT
374 none
376 NOTES
378 EXAMPLE
380 BUGS
382 SEE ALSO
384 INTERNALS
386 HISTORY
387 24-12-95 digulla created
389 ******************************************************************************/
391 AROS_GET_SYSBASE_OK
392 RTData * rtd;
393 va_list args;
394 Resource * rtnew;
396 if (!(rtd = GetRTData ()) )
397 return;
399 if (!(rtnew = AllocMem (GetRTSize(rtt), MEMF_ANY|MEMF_CLEAR)) )
401 D(bug("RT_IntAdd: Out of memory\n"));
403 else
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);
412 va_end (args);
414 AddTail ((struct List *)&rtd->rtd_ResHash[rtt][CALCHASH(HASH_BASE(rtnew))]
415 , (struct Node *)rtnew
418 } /* RT_IntTrack */
420 /*****************************************************************************
422 NAME */
423 #include <aros/rt.h>
425 IPTR RT_IntCheck (
427 /* SYNOPSIS */
428 int rtt,
429 const char * file,
430 int line,
431 int op,
432 ...)
434 /* FUNCTION
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
438 be traced:
440 RTT_ALLOCMEM: APTR memPtr,
441 ULONG size)
443 INPUTS
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
451 RESULT
452 none
454 NOTES
455 All strings must be static.
457 EXAMPLE
459 BUGS
461 SEE ALSO
463 INTERNALS
465 HISTORY
466 24-12-95 digulla created
468 ******************************************************************************/
470 RTData * rtd;
471 RTNode * rt;
472 va_list args;
473 IPTR ret;
475 if (!(rtd = GetRTData ()) )
476 return FALSE;
478 va_start (args, op);
480 if (GetRTCheckFunc(rtt))
482 ret = (*(GetRTCheckFunc(rtt)))
484 rtd,
485 rtt,
486 file,
487 line,
489 args
492 else
494 ret = (*(GetRTSearchFunc(rtt)))
496 rtd,
497 rtt,
498 &rt,
499 args
502 if (ret != RT_SEARCH_FOUND)
504 ret = (*(GetRTShowError(rtt)))
506 rtd,
507 rtt,
509 ret,
510 RT_CHECK,
511 file,
512 line,
513 args
518 va_end (args);
520 return ret;
521 } /* RT_IntCheck */
523 /*****************************************************************************
525 NAME */
526 #include <aros/rt.h>
528 IPTR RT_IntFree (
530 /* SYNOPSIS */
531 int rtt,
532 const char * file,
533 int line,
534 ...)
536 /* FUNCTION
537 Stops tracing of a resource. The arguments after
538 line depend on the type of resource to be traced.
540 INPUTS
541 rtt - Type of the resource
542 file - The file RT_IntAdd was called it
543 line - The line of the file
545 RESULT
546 none
548 NOTES
549 All strings must be static.
551 EXAMPLE
553 BUGS
555 SEE ALSO
557 INTERNALS
559 HISTORY
560 24-12-95 digulla created
562 ******************************************************************************/
564 RTData * rtd;
565 IPTR ret;
566 va_list args;
567 RTNode * rt;
569 if (!(rtd = GetRTData ()) )
570 return FALSE;
572 va_start (args, line);
574 ret = (*(GetRTSearchFunc(rtt)))
576 rtd,
577 rtt,
578 &rt,
579 args
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));
589 else
591 ret = (*(GetRTShowError(rtt)))
593 rtd,
594 rtt,
596 ret,
597 RT_FREE,
598 file,
599 line,
600 args
604 va_end (args);
606 return ret;
607 } /* RT_IntFree */
610 /*****************************************************************************
612 NAME */
613 #include <aros/rt.h>
615 void RT_IntEnter (
617 /* SYNOPSIS */
618 const char * function,
619 const char * file,
620 int line)
622 /* 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.
626 INPUTS
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
631 RESULT
632 none
634 NOTES
635 All strings must be static.
637 EXAMPLE
639 BUGS
641 SEE ALSO
643 INTERNALS
645 HISTORY
646 24-12-95 digulla created
648 ******************************************************************************/
650 RTData * rtd;
652 if (!(rtd = GetRTData ()) )
653 return;
655 if (rtd->rtd_StackPtr == 0)
656 return;
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;
663 } /* RT_IntEnter */
666 /*****************************************************************************
668 NAME */
669 #include <aros/rt.h>
671 void RT_IntLeave (
673 /* SYNOPSIS */
674 void)
676 /* FUNCTION
677 Tells the RT that a the function has been left.
679 INPUTS
680 none
682 RESULT
683 none
685 NOTES
687 EXAMPLE
689 BUGS
691 SEE ALSO
693 INTERNALS
695 HISTORY
696 24-12-95 digulla created
698 ******************************************************************************/
700 RTData * rtd;
702 if (!(rtd = GetRTData ()) )
703 return;
705 if (rtd->rtd_StackPtr == STACKDEPTH)
706 return;
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 ++;
713 } /* RT_IntLeave */
716 /*****************************************************************************
718 NAME */
719 #include <aros/rt.h>
721 void RT_ShowStack (
723 /* SYNOPSIS */
724 RTNode * node)
726 /* FUNCTION
727 Prints the contents of the callstack stored in the node.
729 INPUTS
730 node - The node with the callstack to be printed
732 RESULT
733 none
735 NOTES
737 EXAMPLE
739 BUGS
741 SEE ALSO
743 INTERNALS
745 HISTORY
746 24-12-95 digulla created
748 ******************************************************************************/
750 #if 0
751 RTData * rtd;
752 int t;
754 if (!(rtd = GetRTData ()) )
755 return;
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
763 #endif
764 } /* RT_ShowStack */
767 /*****************************************************************************
769 NAME */
770 #include <aros/rt.h>
772 void RT_ShowRTStack (
774 /* SYNOPSIS */
775 void)
777 /* FUNCTION
778 Prints the contents of the callstack built by RT_Enter() and
779 RT_Leave().
781 INPUTS
782 none
784 RESULT
785 none
787 NOTES
789 EXAMPLE
791 BUGS
793 SEE ALSO
795 INTERNALS
797 HISTORY
798 24-12-95 digulla created
800 ******************************************************************************/
802 RTData * rtd;
803 int t;
805 if (!(rtd = GetRTData ()) )
806 return;
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 /*****************************************************************************
821 NAME */
822 #include <aros/rt.h>
824 void RT_FreeResource (
826 /* SYNOPSIS */
827 RTData * rtd,
828 int rtt,
829 RTNode * rtnode)
831 /* FUNCTION
832 Free a resource after the task that allocated it, died. Also
833 print a nasty message about this.
835 INPUTS
836 rt - The node with the resource to be freed.
838 RESULT
839 none
841 NOTES
843 EXAMPLE
845 BUGS
847 SEE ALSO
849 INTERNALS
850 Don't free the node or remove it from the list. This is done
851 elsewhere.
853 HISTORY
854 24-12-95 digulla created
856 ******************************************************************************/
858 AROS_GET_SYSBASE_OK
859 if (!rtd && !(rtd = GetRTData ()))
860 return;
862 if (!(rtnode->Flags & RTNF_DONT_FREE) )
864 /* Print an error */
865 (void) (*(GetRTShowError(rtt)))
867 rtd,
868 rtt,
869 rtnode,
870 0UL,
871 RT_EXIT,
872 NULL,
874 NULL
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 /**************************************
889 Utility functions
890 **************************************/
892 BOOL CheckPtr (APTR ptr, ULONG flags)
896 (!ptr && !(flags & NULL_PTR))
897 || (((IPTR)ptr & 3) && (flags & ALIGNED_PTR))
900 return FALSE;
904 return TRUE;
905 } /* CheckPtr */
907 BOOL CheckArea (APTR ptr, ULONG size, ULONG flags)
911 (size & 0x8000000)
912 || !CheckPtr (ptr+size-1, flags)
914 return FALSE;
916 return TRUE;
917 } /* CheckArea */
919 IPTR RT_Search (RTData * rtd, int rtt, RTNode ** rtptr, va_list args)
921 Resource * rt;
922 APTR * res;
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;
937 } /* RT_Search */