use struct timeval to obtain the cputime. disable display atm until the code is corre...
[AROS.git] / workbench / c / TaskList.c
blobc40501e97ee8c584801e3cf4683c75af7605fdf4
1 /*
2 Copyright © 1995-2015, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: english
7 */
9 /******************************************************************************
12 NAME
14 TaskList
16 SYNOPSIS
18 (N/A)
20 LOCATION
24 FUNCTION
26 Prints a list of all tasks.
28 INPUTS
30 RESULT
32 NOTES
34 EXAMPLE
36 BUGS
38 SEE ALSO
40 INTERNALS
42 HISTORY
44 ******************************************************************************/
46 #include <exec/memory.h>
47 #include <exec/tasks.h>
48 #include <exec/execbase.h>
49 #include <proto/exec.h>
50 #include <proto/timer.h>
51 #include <aros/debug.h>
52 #include <devices/timer.h>
53 #include <dos/dosextens.h>
54 #include <proto/dos.h>
55 #include <proto/task.h>
57 #include <resources/task.h>
59 const TEXT version[] = "$VER: tasklist 41.4 (29.4.2015)\n";
61 APTR TaskResBase = NULL;
62 ULONG eclock;
64 struct task
66 STRPTR name;
67 APTR address;
68 WORD type;
69 WORD state;
70 IPTR stacksize;
71 IPTR stackused;
72 WORD pri;
73 struct timeval cputime;
76 static int addtask(struct Task *task, struct task **t, STRPTR *e)
78 STRPTR s1,s2;
79 struct TagItem QueryTaskTags[] =
81 {TaskTag_CPUTime , &(*t)->cputime },
82 {TAG_DONE , 0 }
85 QueryTaskTagList(task, QueryTaskTags);
87 (*t)->address=task;
88 (*t)->type=task->tc_Node.ln_Type;
89 (*t)->pri =(WORD)task->tc_Node.ln_Pri;
90 (*t)->state=task->tc_State;
91 (*t)->stacksize=(STRPTR)task->tc_SPUpper-(STRPTR)task->tc_SPLower;
92 #if AROS_STACK_GROWS_DOWNWARDS
93 (*t)->stackused=(STRPTR)task->tc_SPUpper-SP_OFFSET-(STRPTR)task->tc_SPReg;
94 #else
95 (*t)->stackused=(STRPTR)task->tc_SPReg-SP_OFFSET-(STRPTR)task->tc_SPLower;
96 #endif
97 if(task->tc_State==TS_RUN)
98 /* The tc_SPReg for the actual process is invalid
99 if it had no context switch yet */
100 (*t)->stackused=0;
101 s1=task->tc_Node.ln_Name;
102 if(task->tc_Node.ln_Type==NT_PROCESS&&((struct Process *)task)->pr_CLI)
104 /* TODO: Use cli_CommandName field for the name */
105 (*t)->type=-1;
107 if(s1!=NULL)
109 s2=s1;
110 while(*s2++)
112 while(s2>s1)
114 if(*e<=(STRPTR)*t)
115 return 0;
116 *--(*e)=*--s2;
119 if((STRPTR)(*t+1)>*e)
120 return 0;
121 (*t)->name=*e;
122 ++*t;
123 return 1;
126 static int fillbuffer(struct task **buffer, IPTR size)
128 STRPTR end=(STRPTR)*buffer+size;
129 struct Task *task;
130 Disable();
131 if(!addtask(FindTask(NULL),buffer,&end))
133 Enable();
134 return 0;
136 for(task=(struct Task *)SysBase->TaskReady.lh_Head;
137 task->tc_Node.ln_Succ!=NULL;
138 task=(struct Task *)task->tc_Node.ln_Succ)
140 if(!addtask(task,buffer,&end))
142 Enable();
143 return 0;
146 for(task=(struct Task *)SysBase->TaskWait.lh_Head;
147 task->tc_Node.ln_Succ!=NULL;
148 task=(struct Task *)task->tc_Node.ln_Succ)
150 if(!addtask(task,buffer,&end))
152 Enable();
153 return 0;
156 Enable();
157 return 1;
160 int __nocommandline;
162 int main(void)
164 IPTR size;
165 struct task *buffer,*tasks,*tasks2;
167 /* Is all this code really needed to read the EClock frequency? sigh... */
168 struct TimerBase *TimerBase = NULL;
169 struct EClockVal ec;
170 struct MsgPort *port = CreateMsgPort();
171 struct timerequest *io = (struct timerequest *)CreateIORequest(port, sizeof(struct timerequest));
172 OpenDevice("timer.device", UNIT_VBLANK, (struct IORequest *)io, 0);
173 TimerBase = (struct TimerBase *)io->tr_node.io_Device;
174 eclock = ReadEClock(&ec);
175 CloseDevice((struct IORequest *)io);
176 DeleteIORequest((struct IORequest *)io);
177 DeleteMsgPort(port);
179 TaskResBase = OpenResource("task.resource");
181 for(size=2048;;size+=2048)
183 buffer=AllocVec(size,MEMF_ANY);
184 if(buffer==NULL)
186 FPuts(Output(),"Not Enough memory for task buffer\n");
187 return 20;
189 tasks=buffer;
190 if(fillbuffer(&tasks,size))
192 FPuts(Output(),"Address\t\tType\tPri\tState\tCPU Time\tStack\tUsed\tName\n");
193 for(tasks2=buffer;tasks2<tasks;tasks2++)
195 #if (0)
196 ULONG time;
198 /* If eclock was not null, use it */
199 if (eclock)
200 time = tasks2->cputime / eclock;
201 else /* Otherwise we cannot calculate the cpu time :/ */
202 time = 0;
203 #endif
205 IPTR args[10];
206 args[0]=(IPTR)tasks2->address;
207 args[1]=(IPTR)(tasks2->type==NT_TASK?"task":
208 tasks2->type==NT_PROCESS?"process":"CLI");
209 args[2]=tasks2->pri;
210 args[3]=(IPTR)(tasks2->state==TS_RUN?"running":
211 tasks2->state==TS_READY?"ready":"waiting");
213 #if (0)
214 args[6]=time % 60;
215 time /= 60;
216 args[5]=time % 60;
217 time /= 60;
218 args[4]=time;
219 #endif
220 args[7]=tasks2->stacksize;
221 args[8]=tasks2->stackused;
222 args[9]=tasks2->name!=NULL?(IPTR)tasks2->name:0;
223 VPrintf("0x%08.lx\t%s\t%ld\t%s\t%02ld:%02ld:%02ld\t%ld\t%ld\t%s\n",args);
225 FreeVec(buffer);
226 return 0;
228 FreeVec(buffer);