# make sure the interrupt vectors are enabled on the core asking for them
[AROS.git] / workbench / c / TaskList.c
blob61e1f1c9a1453f6ef1b56015ca178eacbcce6b5c
1 /*
2 Copyright © 1995-2017, 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 int __nocommandline;
48 #include <exec/memory.h>
49 #include <exec/tasks.h>
50 #include <exec/execbase.h>
51 #include <proto/exec.h>
52 #include <proto/timer.h>
53 #include <aros/debug.h>
54 #include <devices/timer.h>
55 #include <dos/dosextens.h>
56 #include <proto/dos.h>
57 #include <proto/task.h>
59 #include <resources/task.h>
61 const TEXT version[] = "$VER: TaskList 42.2 (21.01.2017)\n";
63 APTR TaskResBase = NULL;
64 ULONG eclock;
66 struct task
68 struct Node node;
69 APTR address;
70 WORD state;
71 IPTR stacksize;
72 IPTR stackused;
73 struct timeval cputime;
76 static int addtask(struct List *tasks, struct Task *task)
78 struct task *t;
79 STRPTR s1,s2, e = NULL;
80 #if defined(__AROS__)
81 struct TagItem QueryTaskTags[] =
83 {TaskTag_CPUTime , 0 },
84 {TAG_DONE , 0 }
86 #endif
88 if (task->tc_Node.ln_Type == NT_PROCESS && ((struct Process *)task)->pr_CLI)
90 struct CommandLineInterface *cli = BADDR(((struct Process *)task)->pr_CLI);
92 if (cli->cli_CommandName)
93 s1 = AROS_BSTR_ADDR(cli->cli_CommandName);
94 else
95 s1 = task->tc_Node.ln_Name;
97 else
98 s1 = task->tc_Node.ln_Name;
100 if (s1 == NULL)
101 t = AllocVec(sizeof(struct task), MEMF_CLEAR|MEMF_PUBLIC);
102 else
104 t = AllocVec(sizeof(struct task) + strlen(s1) + 1, MEMF_CLEAR|MEMF_PUBLIC);
105 e = (STRPTR)&t[1] + strlen(s1);
108 if (!t)
109 return 0;
111 #if defined(__AROS__)
112 QueryTaskTags[0].ti_Data = (IPTR)&t->cputime;
113 QueryTaskTagList(task, QueryTaskTags);
114 #endif
116 t->address = task;
117 if (task->tc_Node.ln_Type == NT_PROCESS && ((struct Process *)task)->pr_CLI)
118 t->node.ln_Type = -1;
119 else
120 t->node.ln_Type = task->tc_Node.ln_Type;
121 t->node.ln_Pri = task->tc_Node.ln_Pri;
122 t->state = task->tc_State;
123 t->stacksize = (STRPTR)task->tc_SPUpper - (STRPTR)task->tc_SPLower;
124 #if AROS_STACK_GROWS_DOWNWARDS
125 t->stackused = (STRPTR)task->tc_SPUpper - SP_OFFSET - (STRPTR)task->tc_SPReg;
126 #else
127 t->stackused = (STRPTR)task->tc_SPReg - SP_OFFSET - (STRPTR)task->tc_SPLower;
128 #endif
129 if (task->tc_State == TS_RUN)
131 /* The tc_SPReg for the actual process is invalid
132 if it had no context switch yet */
133 t->stackused = 0;
136 if (s1 != NULL)
138 s2 = s1;
140 while (*s2++)
143 while (s2 > s1)
144 *--e=*--s2;
146 t->node.ln_Name = e;
149 AddTail(tasks, &t->node);
151 return 1;
154 static int fillbuffer(struct List *tasks)
156 struct Task *task;
158 #if !defined(__AROS__)
159 Disable();
161 if (!addtask(task, FindTask(NULL)))
163 Enable();
164 return RETURN_FAIL;
166 for (task = (struct Task *)SysBase->TaskReady.lh_Head;
167 task->tc_Node.ln_Succ != NULL;
168 task = (struct Task *)task->tc_Node.ln_Succ)
170 if (!addtask(tasks, task))
172 Enable();
173 return RETURN_FAIL;
176 for (task = (struct Task *)SysBase->TaskWait.lh_Head;
177 task->tc_Node.ln_Succ != NULL;
178 task = (struct Task *)task->tc_Node.ln_Succ)
180 if (!addtask(tasks, task))
182 Enable();
183 return RETURN_FAIL;
186 Enable();
187 #else
188 struct TaskList *taskList;
190 taskList = LockTaskList(LTF_ALL);
191 while ((task = NextTaskEntry(taskList, LTF_ALL)) != NULL)
193 if (!addtask(tasks, task))
195 break;
198 UnLockTaskList(taskList, LTF_ALL);
199 #endif
201 return RETURN_OK;
204 int main(void)
206 struct task *currentTask, *tmpTask;
207 struct List tasks;
208 int retval;
210 #if defined(__AROS__)
211 TaskResBase = OpenResource("task.resource");
212 if (!TaskResBase) {
213 PutStr("Can't open task.resource\n");
214 return RETURN_FAIL;
216 #endif
218 NEWLIST(&tasks);
220 retval = fillbuffer(&tasks);
222 if (!IsListEmpty(&tasks))
224 PutStr("Address\t\tType\tPri\tState\tCPU Time\tStack\tUsed\tName\n");
225 ForeachNodeSafe(&tasks, currentTask, tmpTask)
227 ULONG time;
229 Remove((struct Node *)currentTask);
231 time = currentTask->cputime.tv_secs;
232 Printf("0x%08.ix\t%s\t%ld\t%s\t%03ld:%02ld:%02ld\t%id\t%id\t%s\n",
233 currentTask->address,
234 (currentTask->node.ln_Type == NT_TASK) ? "task" :
235 (currentTask->node.ln_Type == NT_PROCESS) ? "process" : "CLI",
236 (ULONG)currentTask->node.ln_Pri,
237 (currentTask->state == TS_RUN) ? "running" :
238 (currentTask->state == TS_READY) ? "ready" : "waiting",
239 (time / 60 / 60), (time / 60) % 60, time % 60,
240 currentTask->stacksize, currentTask->stackused,
241 (currentTask->node.ln_Name != NULL) ? currentTask->node.ln_Name : "(null)");
243 FreeVec(currentTask);
246 return retval;