2 Copyright © 1995-2009, The AROS Development Team. All rights reserved.
9 /******************************************************************************
26 Prints a list of all tasks.
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>
56 /* Dirty hack! Is there a better way? */
57 #include "../../rom/exec/etask.h"
59 const TEXT version
[] = "$VER: tasklist 41.2 (15.5.2009)\n";
75 static int addtask(struct Task
*task
, struct task
**t
, STRPTR
*e
)
78 (*t
)->cputime
= GetIntETask(task
)->iet_CpuTime
;
80 (*t
)->type
=task
->tc_Node
.ln_Type
;
81 (*t
)->pri
=(WORD
)task
->tc_Node
.ln_Pri
;
82 (*t
)->state
=task
->tc_State
;
83 (*t
)->stacksize
=(STRPTR
)task
->tc_SPUpper
-(STRPTR
)task
->tc_SPLower
;
84 #if AROS_STACK_GROWS_DOWNWARDS
85 (*t
)->stackused
=(STRPTR
)task
->tc_SPUpper
-SP_OFFSET
-(STRPTR
)task
->tc_SPReg
;
87 (*t
)->stackused
=(STRPTR
)task
->tc_SPReg
-SP_OFFSET
-(STRPTR
)task
->tc_SPLower
;
89 if(task
->tc_State
==TS_RUN
)
90 /* The tc_SPReg for the actual process is invalid
91 if it had no context switch yet */
93 s1
=task
->tc_Node
.ln_Name
;
94 if(task
->tc_Node
.ln_Type
==NT_PROCESS
&&((struct Process
*)task
)->pr_CLI
)
96 /* TODO: Use cli_CommandName field for the name */
111 if((STRPTR
)(*t
+1)>*e
)
118 static int fillbuffer(struct task
**buffer
, IPTR size
)
120 STRPTR end
=(STRPTR
)*buffer
+size
;
123 if(!addtask(SysBase
->ThisTask
,buffer
,&end
))
128 for(task
=(struct Task
*)SysBase
->TaskReady
.lh_Head
;
129 task
->tc_Node
.ln_Succ
!=NULL
;
130 task
=(struct Task
*)task
->tc_Node
.ln_Succ
)
131 if(!addtask(task
,buffer
,&end
))
136 for(task
=(struct Task
*)SysBase
->TaskWait
.lh_Head
;
137 task
->tc_Node
.ln_Succ
!=NULL
;
138 task
=(struct Task
*)task
->tc_Node
.ln_Succ
)
139 if(!addtask(task
,buffer
,&end
))
153 struct task
*buffer
,*tasks
,*tasks2
;
155 /* Is all this code really needed to read the EClock frequency? sigh... */
156 struct TimerBase
*TimerBase
= NULL
;
158 struct MsgPort
*port
= CreateMsgPort();
159 struct timerequest
*io
= (struct timerequest
*)CreateIORequest(port
, sizeof(struct timerequest
));
160 OpenDevice("timer.device", UNIT_VBLANK
, (struct IORequest
*)io
, 0);
161 TimerBase
= (struct TimerBase
*)io
->tr_node
.io_Device
;
162 eclock
= ReadEClock(&ec
);
163 CloseDevice((struct IORequest
*)io
);
164 DeleteIORequest((struct IORequest
*)io
);
167 for(size
=2048;;size
+=2048)
169 buffer
=AllocVec(size
,MEMF_ANY
);
172 FPuts(Output(),"Not Enough memory for task buffer\n");
176 if(fillbuffer(&tasks
,size
))
178 FPuts(Output(),"Address\t\tType\tPri\tState\tCPU Time\tStack\tUsed\tName\n");
179 for(tasks2
=buffer
;tasks2
<tasks
;tasks2
++)
183 /* If eclock was not null, use it */
185 time
= tasks2
->cputime
/ eclock
;
186 else /* Otherwise we cannot calculate the cpu time :/ */
190 args
[0]=(IPTR
)tasks2
->address
;
191 args
[1]=(IPTR
)(tasks2
->type
==NT_TASK
?"task":
192 tasks2
->type
==NT_PROCESS
?"process":"CLI");
194 args
[3]=(IPTR
)(tasks2
->state
==TS_RUN
?"running":
195 tasks2
->state
==TS_READY
?"ready":"waiting");
201 args
[7]=tasks2
->stacksize
;
202 args
[8]=tasks2
->stackused
;
203 args
[9]=tasks2
->name
!=NULL
?(IPTR
)tasks2
->name
:0;
204 VPrintf("0x%08.lx\t%s\t%ld\t%s\t%02ld:%02ld:%02ld\t%ld\t%ld\t%s\n",args
);