2 Copyright © 1995-2009, The AROS Development Team. All rights reserved.
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";
38 static int addtask(struct Task
*task
, struct task
**t
, STRPTR
*e
)
41 (*t
)->cputime
= GetIntETask(task
)->iet_CpuTime
;
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
;
50 (*t
)->stackused
=(STRPTR
)task
->tc_SPReg
-SP_OFFSET
-(STRPTR
)task
->tc_SPLower
;
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 */
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 */
81 static int fillbuffer(struct task
**buffer
, IPTR size
)
83 STRPTR end
=(STRPTR
)*buffer
+size
;
86 if(!addtask(SysBase
->ThisTask
,buffer
,&end
))
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
))
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
))
116 struct task
*buffer
,*tasks
,*tasks2
;
118 /* Is all this code really needed to read the EClock frequency? sigh... */
119 struct TimerBase
*TimerBase
= NULL
;
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
);
130 for(size
=2048;;size
+=2048)
132 buffer
=AllocVec(size
,MEMF_ANY
);
135 FPuts(Output(),"Not Enough memory for task buffer\n");
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
++)
146 /* If eclock was not null, use it */
148 time
= tasks2
->cputime
/ eclock
;
149 else /* Otherwise we cannot calculate the cpu time :/ */
153 args
[0]=(IPTR
)tasks2
->address
;
154 args
[1]=(IPTR
)(tasks2
->type
==NT_TASK
?"task":
155 tasks2
->type
==NT_PROCESS
?"process":"CLI");
157 args
[3]=(IPTR
)(tasks2
->state
==TS_RUN
?"running":
158 tasks2
->state
==TS_READY
?"ready":"waiting");
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
);