2 Copyright © 1995-2015, 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>
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
;
73 struct timeval cputime
;
76 static int addtask(struct Task
*task
, struct task
**t
, STRPTR
*e
)
79 struct TagItem QueryTaskTags
[] =
81 {TaskTag_CPUTime
, &(*t
)->cputime
},
85 QueryTaskTagList(task
, QueryTaskTags
);
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
;
95 (*t
)->stackused
=(STRPTR
)task
->tc_SPReg
-SP_OFFSET
-(STRPTR
)task
->tc_SPLower
;
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 */
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 */
119 if((STRPTR
)(*t
+1)>*e
)
126 static int fillbuffer(struct task
**buffer
, IPTR size
)
128 STRPTR end
=(STRPTR
)*buffer
+size
;
131 if(!addtask(FindTask(NULL
),buffer
,&end
))
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
))
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
))
165 struct task
*buffer
,*tasks
,*tasks2
;
167 /* Is all this code really needed to read the EClock frequency? sigh... */
168 struct TimerBase
*TimerBase
= NULL
;
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
);
179 TaskResBase
= OpenResource("task.resource");
181 for(size
=2048;;size
+=2048)
183 buffer
=AllocVec(size
,MEMF_ANY
);
186 FPuts(Output(),"Not Enough memory for task buffer\n");
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
++)
198 /* If eclock was not null, use it */
200 time
= tasks2
->cputime
/ eclock
;
201 else /* Otherwise we cannot calculate the cpu time :/ */
206 args
[0]=(IPTR
)tasks2
->address
;
207 args
[1]=(IPTR
)(tasks2
->type
==NT_TASK
?"task":
208 tasks2
->type
==NT_PROCESS
?"process":"CLI");
210 args
[3]=(IPTR
)(tasks2
->state
==TS_RUN
?"running":
211 tasks2
->state
==TS_READY
?"ready":"waiting");
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
);