wip commit. acpi button driver.
[AROS.git] / compiler / arossupport / rt_exec.c
blob69cdac1b29e46230e0bc8c8bd434340d914b1ada
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Basic functions for ressource tracking
6 Lang: english
7 */
9 #include "rt.h"
10 #if 0
11 #define ENABLE_RT 0 /* no RT inside this file */
12 #define RT_INTERNAL 1
13 #include <aros/rt.h>
15 #include <exec/lists.h>
16 #include <aros/system.h>
17 #include <exec/execbase.h>
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include "etask.h"
21 #endif
22 #include <exec/tasks.h>
23 #include <exec/ports.h>
24 #include <exec/memory.h>
25 #include <stdarg.h>
26 #include <proto/exec.h>
27 #include <proto/arossupport.h>
28 #include <proto/alib.h>
30 typedef struct
32 RTNode Node;
33 APTR Memory;
34 ULONG Size;
35 ULONG Flags;
37 MemoryResource;
39 typedef struct
41 RTNode Node;
42 struct MsgPort * Port;
44 PortResource;
46 typedef struct
48 RTNode Node;
49 struct Library * Lib;
50 STRPTR Name;
51 ULONG Version;
53 LibraryResource;
55 static IPTR RT_AllocMem (RTData * rtd, MemoryResource * rt, va_list args, BOOL * success);
56 static IPTR RT_FreeMem (RTData * rtd, MemoryResource * rt);
57 static IPTR RT_SearchMem (RTData * rtd, int rtt, MemoryResource ** rtptr, va_list args);
58 static IPTR RT_ShowErrorMem (RTData * rtd, int rtt, MemoryResource *, IPTR, int, const char * file, ULONG line, va_list);
60 static IPTR RT_AllocVec (RTData * rtd, MemoryResource * rt, va_list args, BOOL * success);
61 static IPTR RT_FreeVec (RTData * rtd, MemoryResource * rt);
62 static IPTR RT_SearchVec (RTData * rtd, int rtt, MemoryResource ** rtptr, va_list args);
63 static IPTR RT_ShowErrorVec (RTData * rtd, int, MemoryResource *, IPTR, int, const char * file, ULONG line, va_list);
65 static IPTR RT_CreatePort (RTData * rtd, PortResource * rt, va_list args, BOOL * success);
66 static IPTR RT_DeletePort (RTData * rtd, PortResource * rt);
67 static IPTR RT_ShowErrorPort (RTData * rtd, int, PortResource *, IPTR, int, const char * file, ULONG line, va_list);
68 static IPTR RT_CheckPort (RTData * rtd, int desc, const char * file, ULONG line, ULONG op, va_list args);
70 static IPTR RT_OpenLibrary (RTData * rtd, LibraryResource * rt, va_list args, BOOL * success);
71 static IPTR RT_CloseLibrary (RTData * rtd, LibraryResource * rt);
72 static IPTR RT_ShowErrorLib (RTData * rtd, int, LibraryResource *, IPTR, int, const char * file, ULONG line, va_list);
74 static const RTDesc RT_ExecResources[] =
76 { /* RTT_ALLOCMEM */
77 sizeof (MemoryResource),
78 (RT_AllocFunc) RT_AllocMem,
79 (RT_FreeFunc) RT_FreeMem,
80 (RT_SearchFunc)RT_SearchMem,
81 (RT_ShowError) RT_ShowErrorMem,
82 NULL, /* Check */
84 { /* RTT_ALLOCVEC */
85 sizeof (MemoryResource),
86 (RT_AllocFunc) RT_AllocVec,
87 (RT_FreeFunc) RT_FreeVec,
88 (RT_SearchFunc)RT_SearchVec,
89 (RT_ShowError) RT_ShowErrorVec,
90 NULL, /* Check */
92 { /* RTT_PORT */
93 sizeof (PortResource),
94 (RT_AllocFunc) RT_CreatePort,
95 (RT_FreeFunc) RT_DeletePort,
96 RT_Search,
97 (RT_ShowError) RT_ShowErrorPort,
98 (RT_CheckFunc) RT_CheckPort,
100 { /* RTT_LIBRARY */
101 sizeof (LibraryResource),
102 (RT_AllocFunc) RT_OpenLibrary,
103 (RT_FreeFunc) RT_CloseLibrary,
104 RT_Search,
105 (RT_ShowError) RT_ShowErrorLib,
106 NULL, /* Check */
110 void RT_InitExec (void)
112 RT_Resources[RTT_ALLOCMEM] = &RT_ExecResources[0];
113 RT_Resources[RTT_ALLOCVEC] = &RT_ExecResources[1];
114 RT_Resources[RTT_PORT] = &RT_ExecResources[2];
115 RT_Resources[RTT_LIBRARY] = &RT_ExecResources[3];
118 void RT_ExitExec (void)
122 /**************************************
123 RT Memory
124 **************************************/
126 static IPTR RT_AllocMem (RTData * rtd, MemoryResource * rt, va_list args, BOOL * success)
128 rt->Size = va_arg (args, ULONG);
129 rt->Flags = va_arg (args, ULONG);
131 rt->Memory = AllocMem (rt->Size, rt->Flags);
133 if (rt->Memory)
134 *success = TRUE;
136 return (IPTR)(rt->Memory);
137 } /* RT_AllocMem */
139 static IPTR RT_FreeMem (RTData * rtd, MemoryResource * rt)
141 FreeMem (rt->Memory, rt->Size);
143 return TRUE;
144 } /* RT_FreeMem */
146 static IPTR RT_SearchMem (RTData * rtd, int rtt, MemoryResource ** rtptr,
147 va_list args)
149 MemoryResource * rt;
150 APTR memory;
151 ULONG size;
153 memory = va_arg (args, APTR);
154 size = va_arg (args, ULONG);
156 ForeachNode (&rtd->rtd_ResHash[rtt][CALCHASH(memory)], rt)
158 if (rt->Memory == memory)
160 *rtptr = rt;
162 if (rt->Size != size)
163 return RT_SEARCH_SIZE_MISMATCH;
165 return RT_SEARCH_FOUND;
169 return RT_SEARCH_NOT_FOUND;
170 } /* RT_SearchMem */
172 static IPTR RT_ShowErrorMem (RTData * rtd, int rtt, MemoryResource * rt,
173 IPTR ret, int mode, const char * file, ULONG line, va_list args)
175 const char * modestr = (mode == RT_FREE) ? "Free" : "Check";
176 APTR memory;
177 ULONG size;
179 if (mode != RT_EXIT)
181 memory = va_arg (args, APTR);
182 size = va_arg (args, ULONG);
184 switch (ret)
186 case RT_SEARCH_FOUND:
187 if (rt->Node.Flags & RTNF_DONT_FREE)
189 kprintf ("RT%s: Try to free read-only resource: Memory\n"
190 " %s at %s:%d\n"
191 " Added at %s:%d\n"
192 " MemPtr=%p\n"
193 , modestr
194 , modestr
195 , file, line
196 , rt->Node.File, rt->Node.Line
197 , rt->Memory
200 break;
202 case RT_SEARCH_NOT_FOUND:
203 kprintf ("RT%s: Memory not found\n"
204 " %s at %s:%d\n"
205 " MemPtr=%p Size=%ld\n"
206 , modestr
207 , modestr
208 , file, line
209 , memory, size
211 break;
213 case RT_SEARCH_SIZE_MISMATCH:
214 kprintf ("RT%s: Size mismatch (Allocated=%ld, Check=%ld)\n"
215 " %s at %s:%d\n"
216 " AllocMem()'d at %s:%d\n"
217 " MemPtr=%p Size=%ld Flags=%08lx\n"
218 , modestr
219 , rt->Size, size
220 , modestr
221 , file, line
222 , rt->Node.File, rt->Node.Line
223 , rt->Memory, rt->Size, rt->Flags
225 break;
227 } /* switch */
229 else
231 kprintf ("RTExit: Memory was not freed\n"
232 " AllocMem()'d at %s:%d\n"
233 " MemPtr=%p Size=%ld Flags=%08lx\n"
234 , rt->Node.File, rt->Node.Line
235 , rt->Memory, rt->Size, rt->Flags
239 return ret;
240 } /* RT_ShowErrorMem */
242 static IPTR RT_AllocVec (RTData * rtd, MemoryResource * rt, va_list args, BOOL * success)
244 rt->Size = va_arg (args, ULONG);
245 rt->Flags = va_arg (args, ULONG);
247 rt->Memory = AllocVec (rt->Size, rt->Flags);
249 if (rt->Memory)
250 *success = TRUE;
252 return (IPTR)(rt->Memory);
253 } /* RT_AllocVec */
255 static IPTR RT_FreeVec (RTData * rtd, MemoryResource * rt)
257 if (rt)
258 FreeVec (rt->Memory);
260 return TRUE;
261 } /* RT_FreeVec */
263 static IPTR RT_SearchVec (RTData * rtd, int rtt, MemoryResource ** rtptr,
264 va_list args)
266 MemoryResource * rt;
267 APTR memory;
269 memory = va_arg (args, APTR);
271 if (!memory)
273 *rtptr = NULL;
274 return RT_SEARCH_FOUND;
277 ForeachNode (&rtd->rtd_ResHash[rtt][CALCHASH(memory)], rt)
279 if (rt->Memory == memory)
281 *rtptr = rt;
283 return RT_SEARCH_FOUND;
287 return RT_SEARCH_NOT_FOUND;
290 static IPTR RT_ShowErrorVec (RTData * rtd, int rtt, MemoryResource * rt,
291 IPTR ret, int mode, const char * file, ULONG line, va_list args)
293 const char * modestr = (mode == RT_FREE) ? "Free" : "Check";
294 APTR memory;
295 ULONG size;
297 if (mode != RT_EXIT)
299 memory = va_arg (args, APTR);
300 size = va_arg (args, ULONG);
302 switch (ret)
304 case RT_SEARCH_FOUND:
305 if (rt && rt->Node.Flags & RTNF_DONT_FREE)
307 kprintf ("RT%s: Try to free read-only resource: Vec-Memory\n"
308 " %s at %s:%d\n"
309 " Added at %s:%d\n"
310 " MemPtr=%p\n"
311 , modestr
312 , modestr
313 , file, line
314 , rt->Node.File, rt->Node.Line
315 , rt->Memory
318 break;
321 case RT_SEARCH_NOT_FOUND:
322 kprintf ("RT%s: Memory not found\n"
323 " %s at %s:%d\n"
324 " MemPtr=%p Size=%ld\n"
325 , modestr
326 , modestr
327 , file, line
328 , memory, size
330 break;
332 } /* switch */
334 else
336 kprintf ("RTExit: Memory was not freed\n"
337 " AllocVec()'d at %s:%d\n"
338 " MemPtr=%p Size=%ld Flags=%08lx\n"
339 , rt->Node.File, rt->Node.Line
340 , rt->Memory, rt->Size, rt->Flags
344 return ret;
345 } /* RT_ShowErrorVec */
348 /**************************************
349 RT Ports
350 **************************************/
352 static IPTR RT_CreatePort (RTData * rtd, PortResource * rt, va_list args, BOOL * success)
354 STRPTR name;
355 LONG pri;
357 name = va_arg (args, STRPTR);
358 pri = va_arg (args, LONG);
360 if (!CheckPtr (name, NULL_PTR))
362 kprintf ("CreatePort(): Illegal name pointer\n"
363 " name=%p at %s:%d\n"
364 , name
365 , rt->Node.File, rt->Node.Line
367 return 0ul;
370 rt->Port = CreatePort (name, pri);
372 if (rt->Port)
373 *success = TRUE;
375 return (IPTR)(rt->Port);
376 } /* RT_CreatePort */
378 static IPTR RT_DeletePort (RTData * rtd, PortResource * rt)
380 DeletePort (rt->Port);
382 return TRUE;
383 } /* RT_ClosePort */
385 static IPTR RT_ShowErrorPort (RTData * rtd, int rtt, PortResource * rt,
386 IPTR ret, int mode, const char * file, ULONG line, va_list args)
388 if (mode != RT_EXIT)
390 const char * modestr = (mode == RT_FREE) ? "Close" : "Check";
391 struct MsgPort * port;
393 port = va_arg (args, struct MsgPort *);
395 switch (ret)
397 case RT_SEARCH_FOUND:
398 if (rt->Node.Flags & RTNF_DONT_FREE)
400 kprintf ("RT%s: Try to free read-only resource: MsgPort\n"
401 " %s at %s:%d\n"
402 " Added at %s:%d\n"
403 " Port=%p (Name=%s Pri=%d)\n"
404 , modestr
405 , modestr
406 , file, line
407 , rt->Node.File, rt->Node.Line
408 , rt->Port
409 , rt->Port->mp_Node.ln_Name
410 ? rt->Port->mp_Node.ln_Name
411 : NULL
412 , rt->Port->mp_Node.ln_Pri
415 break;
417 case RT_SEARCH_NOT_FOUND:
418 kprintf ("RT%s: Port not found\n"
419 " %s at %s:%d\n"
420 " Port=%p\n"
421 , modestr
422 , modestr
423 , file, line
424 , port
426 break;
428 } /* switch */
430 else
432 kprintf ("RTExit: Port was not closed\n"
433 " Opened at %s:%d\n"
434 " Port=%p (Name=%s Pri=%d)\n"
435 , rt->Node.File, rt->Node.Line
436 , rt->Port
437 , rt->Port->mp_Node.ln_Name
438 ? rt->Port->mp_Node.ln_Name
439 : NULL
440 , rt->Port->mp_Node.ln_Pri
444 return ret;
445 } /* RT_ShowErrorPort */
447 static IPTR RT_CheckPort (RTData * rtd, int rtt,
448 const char * file, ULONG line,
449 ULONG op, va_list args)
451 PortResource * rt;
452 APTR prt = &rt;
454 if (RT_Search (rtd, rtt, (RTNode **)prt, args) != RT_SEARCH_FOUND)
455 rt = NULL;
457 switch (op)
459 case RTTO_PutMsg:
461 struct MsgPort * port;
462 struct Message * message;
464 port = va_arg (args, struct MsgPort *);
465 message = va_arg (args, struct Message *);
467 if (!rt)
469 kprintf ("PutMsg(): Illegal port pointer\n"
470 " Port=%p Message=%p at %s:%d\n"
471 , port, message
472 , file, line
475 return -1;
477 else if (CheckPtr (message, 0))
479 kprintf ("PutMsg(): Illegal message pointer\n"
480 " Port=%p Message=%p at %s:%d\n"
481 , port, message
482 , file, line
485 return -1;
488 PutMsg (port, message);
490 return 0;
493 case RTTO_GetMsg:
495 struct MsgPort * port;
497 port = va_arg (args, struct MsgPort *);
499 if (!rt)
501 kprintf ("GetMsg(): Illegal port pointer\n"
502 " Port=%p at %s:%d\n"
503 , port
504 , file, line
507 return 0L;
510 return (IPTR) GetMsg (port);
513 } /* switch (op) */
515 return 0L;
516 } /* RT_CheckPort */
519 /**************************************
520 RT Libraries
521 **************************************/
523 static IPTR RT_OpenLibrary (RTData * rtd, LibraryResource * rt, va_list args, BOOL * success)
525 rt->Name = va_arg (args, STRPTR);
526 rt->Version = va_arg (args, ULONG);
528 rt->Lib = OpenLibrary (rt->Name, rt->Version);
530 if (rt->Lib)
531 *success = TRUE;
533 return (IPTR)(rt->Lib);
534 } /* RT_OpenLibrary */
536 static IPTR RT_CloseLibrary (RTData * rtd, LibraryResource * rt)
538 CloseLibrary (rt->Lib);
540 return TRUE;
541 } /* RT_CloseLibrary */
543 static IPTR RT_ShowErrorLib (RTData * rtd, int rtt, LibraryResource * rt,
544 IPTR ret, int mode, const char * file, ULONG line, va_list args)
547 if (mode != RT_EXIT)
549 const char * modestr = (mode == RT_FREE) ? "Free" : "Check";
550 struct Library * base;
552 base = va_arg (args, struct Library *);
554 switch (ret)
556 case RT_SEARCH_FOUND:
557 if (rt->Node.Flags & RTNF_DONT_FREE)
559 kprintf ("RT%s: Try to free read-only resource: Library\n"
560 " %s at %s:%d\n"
561 " Added at %s:%d\n"
562 " LibBase=%p\n"
563 , modestr
564 , modestr
565 , file, line
566 , rt->Node.File, rt->Node.Line
567 , rt->Lib
570 break;
572 case RT_SEARCH_NOT_FOUND:
573 kprintf ("RT%s: Library not found\n"
574 " %s at %s:%d\n"
575 " Base=%p\n"
576 , modestr
577 , modestr
578 , file, line
579 , base
581 break;
583 } /* switch */
585 else
587 kprintf ("RTExit: Library was not closed\n"
588 " Opened at %s:%d\n"
589 " Base=%p Name=%s Version=%ld\n"
590 , rt->Node.File, rt->Node.Line
591 , rt->Lib, rt->Name, rt->Version
595 return ret;
596 } /* RT_ShowErrorLib */