Fixed out-by-one error in previous commit.
[AROS.git] / workbench / c / TaskList.c
blob646292f3fe2fc4eb343e30cdc14478d69aa02603
1 /*
2 Copyright © 1995-2009, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: english
7 */
9 #include <exec/memory.h>
10 #include <exec/tasks.h>
11 #include <exec/execbase.h>
12 #include <proto/exec.h>
13 #include <proto/timer.h>
14 #include <aros/debug.h>
15 #include <devices/timer.h>
16 #include <dos/dosextens.h>
17 #include <proto/dos.h>
19 /* Dirty hack! Is there a better way? */
20 #include "../../rom/exec/etask.h"
22 const TEXT version[] = "$VER: tasklist 41.2 (15.5.2009)\n";
24 ULONG eclock;
26 struct task
28 STRPTR name;
29 APTR address;
30 WORD type;
31 WORD state;
32 IPTR stacksize;
33 IPTR stackused;
34 WORD pri;
35 UQUAD cputime;
38 static int addtask(struct Task *task, struct task **t, STRPTR *e)
40 STRPTR s1,s2;
41 (*t)->cputime = GetIntETask(task)->iet_CpuTime;
42 (*t)->address=task;
43 (*t)->type=task->tc_Node.ln_Type;
44 (*t)->pri =(WORD)task->tc_Node.ln_Pri;
45 (*t)->state=task->tc_State;
46 (*t)->stacksize=(STRPTR)task->tc_SPUpper-(STRPTR)task->tc_SPLower;
47 #if AROS_STACK_GROWS_DOWNWARDS
48 (*t)->stackused=(STRPTR)task->tc_SPUpper-SP_OFFSET-(STRPTR)task->tc_SPReg;
49 #else
50 (*t)->stackused=(STRPTR)task->tc_SPReg-SP_OFFSET-(STRPTR)task->tc_SPLower;
51 #endif
52 if(task->tc_State==TS_RUN)
53 /* The tc_SPReg for the actual process is invalid
54 if it had no context switch yet */
55 (*t)->stackused=0;
56 s1=task->tc_Node.ln_Name;
57 if(task->tc_Node.ln_Type==NT_PROCESS&&((struct Process *)task)->pr_CLI)
59 /* TODO: Use cli_CommandName field for the name */
60 (*t)->type=-1;
62 if(s1!=NULL)
64 s2=s1;
65 while(*s2++)
67 while(s2>s1)
69 if(*e<=(STRPTR)t)
70 return 0;
71 *--(*e)=*--s2;
74 if((STRPTR)(*t+1)>*e)
75 return 0;
76 (*t)->name=*e;
77 ++*t;
78 return 1;
81 static int fillbuffer(struct task **buffer, IPTR size)
83 STRPTR end=(STRPTR)*buffer+size;
84 struct Task *task;
85 Disable();
86 if(!addtask(SysBase->ThisTask,buffer,&end))
88 Enable();
89 return 0;
91 for(task=(struct Task *)SysBase->TaskReady.lh_Head;
92 task->tc_Node.ln_Succ!=NULL;
93 task=(struct Task *)task->tc_Node.ln_Succ)
94 if(!addtask(task,buffer,&end))
96 Enable();
97 return 0;
99 for(task=(struct Task *)SysBase->TaskWait.lh_Head;
100 task->tc_Node.ln_Succ!=NULL;
101 task=(struct Task *)task->tc_Node.ln_Succ)
102 if(!addtask(task,buffer,&end))
104 Enable();
105 return 0;
107 Enable();
108 return 1;
111 int __nocommandline;
113 int main(void)
115 IPTR size;
116 struct task *buffer,*tasks,*tasks2;
118 /* Is all this code really needed to read the EClock frequency? sigh... */
119 struct TimerBase *TimerBase = NULL;
120 struct EClockVal ec;
121 struct MsgPort *port = CreateMsgPort();
122 struct timerequest *io = (struct timerequest *)CreateIORequest(port, sizeof(struct timerequest));
123 OpenDevice("timer.device", UNIT_VBLANK, (struct IORequest *)io, 0);
124 TimerBase = (struct TimerBase *)io->tr_node.io_Device;
125 eclock = ReadEClock(&ec);
126 CloseDevice((struct IORequest *)io);
127 DeleteIORequest((struct IORequest *)io);
128 DeleteMsgPort(port);
130 for(size=2048;;size+=2048)
132 buffer=AllocVec(size,MEMF_ANY);
133 if(buffer==NULL)
135 FPuts(Output(),"Not Enough memory for task buffer\n");
136 return 20;
138 tasks=buffer;
139 if(fillbuffer(&tasks,size))
141 FPuts(Output(),"Address\t\tType\tPri\tState\tCPU Time\tStack\tUsed\tName\n");
142 for(tasks2=buffer;tasks2<tasks;tasks2++)
144 ULONG time;
146 /* If eclock was not null, use it */
147 if (eclock)
148 time = tasks2->cputime / eclock;
149 else /* Otherwise we cannot calculate the cpu time :/ */
150 time = 0;
152 IPTR args[10];
153 args[0]=(IPTR)tasks2->address;
154 args[1]=(IPTR)(tasks2->type==NT_TASK?"task":
155 tasks2->type==NT_PROCESS?"process":"CLI");
156 args[2]=tasks2->pri;
157 args[3]=(IPTR)(tasks2->state==TS_RUN?"running":
158 tasks2->state==TS_READY?"ready":"waiting");
159 args[6]=time % 60;
160 time /= 60;
161 args[5]=time % 60;
162 time /= 60;
163 args[4]=time;
164 args[7]=tasks2->stacksize;
165 args[8]=tasks2->stackused;
166 args[9]=tasks2->name!=NULL?(IPTR)tasks2->name:0;
167 VPrintf("0x%08.lx\t%s\t%ld\t%s\t%02ld:%02ld:%02ld\t%ld\t%ld\t%s\n",args);
169 FreeVec(buffer);
170 return 0;
172 FreeVec(buffer);