Port the SB128 code to AROS.
[AROS.git] / workbench / c / StackSnoop.c
blob5c95bf12f699fd1f9b4e8762f44511ef297836fe
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English
7 */
9 #include <exec/exec.h>
10 #include <exec/execbase.h>
11 #include <exec/tasks.h>
12 #include <exec/rawfmt.h>
13 #include <dos/dos.h>
14 #include <proto/exec.h>
15 #include <proto/dos.h>
16 #include <proto/debug.h>
17 #include <proto/alib.h>
19 #include <string.h>
20 #include <setjmp.h>
22 #define ARG_TEMPLATE "TASK/K,DEBUG/S"
24 #define ARG_TASK 0
25 #define ARG_DEBUG 1
26 #define NUM_ARGS 2
28 static struct RDArgs *MyArgs;
29 static IPTR Args[NUM_ARGS];
30 static char s[256];
31 static jmp_buf exit_buf;
33 static UBYTE outbuffer[20000];
34 static LONG outbuffer_size;
36 static void Cleanup(char *msg)
38 WORD rc;
40 if (msg)
42 Printf("stacksnoop: %s\n",msg);
43 rc = RETURN_WARN;
44 } else {
45 rc = RETURN_OK;
48 if (MyArgs) FreeArgs(MyArgs);
50 if (rc != RETURN_OK)
51 longjmp(exit_buf, rc);
54 static void GetArguments(void)
56 if (!(MyArgs = ReadArgs(ARG_TEMPLATE,Args,0)))
58 Fault(IoErr(),0,s,255);
59 Cleanup(s);
63 static int out (const UBYTE * fmt, ...)
65 va_list ap;
66 int result;
68 va_start (ap, fmt);
70 VNewRawDoFmt(fmt, RAWFMTFUNC_STRING, &outbuffer[outbuffer_size], ap);
71 result = strlen(&outbuffer[outbuffer_size]);
73 if (Args[ARG_DEBUG])
74 KPutStr(&outbuffer[outbuffer_size]);
76 outbuffer_size += result;
78 va_end (ap);
80 return result;
84 static void CheckTaskStack(struct Task *task)
86 UBYTE *startcheck, *endcheck;
87 LONG stacksize, stackinc, unusedstack = 0;
89 stacksize = (LONG)( ((UBYTE *)task->tc_SPUpper) - ((UBYTE *)task->tc_SPLower) );
91 #if AROS_STACK_GROWS_DOWNWARDS
92 startcheck = (UBYTE *)task->tc_SPLower;
93 endcheck = ((UBYTE *)task->tc_SPUpper) - 1;
94 stackinc = 1;
95 #else
96 startcheck = ((UBYTE *)task->tc_SPUpper) - 1;
97 endcheck = (UBYTE *)task->tc_SPLower;
98 stackinc = -1;
99 #endif
101 for(; startcheck != endcheck; startcheck += stackinc)
103 if (*startcheck != 0xE1) break;
104 unusedstack++;
107 out("Task %x (%25s) Stack Size =%6d, Left =%6d, Used %s%6d%s\n",
108 task,
109 task->tc_Node.ln_Name ? task->tc_Node.ln_Name : "<NONAME>",
110 stacksize,
111 unusedstack,
112 ((stacksize - unusedstack) < stacksize) ? "=" : ">",
113 stacksize - unusedstack,
114 (unusedstack < 512) ? ": Needs more stack!!!!!!!!!" : "");
117 static void Action(void)
119 struct Task *task;
120 WORD i;
122 Disable();
124 out("\n------------------------------------------------------------------------------\n\n");
126 task = (struct Task *)SysBase->TaskReady.lh_Head;
127 for(i = 0; i < 2;i++)
129 while(task->tc_Node.ln_Succ)
131 CheckTaskStack(task);
133 task = (struct Task *)task->tc_Node.ln_Succ;
134 } /* while(task->tc_Node.ln_Succ) */
136 task = (struct Task *)SysBase->TaskWait.lh_Head;
138 } /* for(i = 0; i < 2;i++) */
139 out("\n");
140 CheckTaskStack(FindTask(NULL));
141 out("\n------------------------------------------------------------------------------\n\n");
143 Enable();
145 PutStr(outbuffer);
148 ULONG __nocommandline = 1;
150 int main(void)
152 int rc;
154 if ((rc = setjmp(exit_buf)) != 0)
155 return rc;
157 GetArguments();
158 Action();
159 Cleanup(0);
160 return 0;