added a new header file to encapsulate compiler-specific stuff.
[newos.git] / apps / top / main.c
blob958076c63ebdc313572d73c731de86b2e59b076d
1 /*
2 ** Copyright 2002, Travis Geiselbrecht. All rights reserved.
3 ** Distributed under the terms of the NewOS License.
4 */
5 #include <sys/syscalls.h>
6 #include <newos/errors.h>
7 #include <string.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <unistd.h>
12 typedef struct thread_time {
13 struct thread_time *next;
15 struct thread_info info;
17 bigtime_t last_user_time;
18 bigtime_t last_kernel_time;
20 bigtime_t delta_user_time;
21 bigtime_t delta_kernel_time;
23 bool touched;
24 } thread_time;
26 static thread_time *times = NULL;
28 static thread_time *find_in_list(thread_id id)
30 thread_time *tt;
32 for(tt = times; tt; tt = tt->next) {
33 if(id == tt->info.id)
34 return tt;
36 return NULL;
39 static void insert_in_list(thread_time *tt)
41 tt->next = times;
42 times = tt;
45 static void prune_untouched(void)
47 thread_time *tt, *last;
49 last = NULL;
50 tt = times;
51 while(tt) {
52 thread_time *temp;
53 if(!tt->touched) {
54 // prune this entry
55 if(!last)
56 times = tt->next;
57 else
58 last->next = tt->next;
59 temp = tt;
60 tt = tt->next;
61 free(temp);
62 } else {
63 tt->touched = false;
64 last = tt;
65 tt = tt->next;
70 // unused
71 #if 0
72 static void sort_times(void)
74 thread_time *curr, *next, *last;
75 bool done;
77 do {
78 done = true;
79 last = NULL;
80 curr = times;
81 while(curr) {
82 next = curr->next;
83 if(!next)
84 break;
86 if((curr->delta_user_time + curr->delta_kernel_time) > (next->delta_user_time + next->delta_kernel_time)) {
87 done = false;
89 // swap the two
90 if(last)
91 times = next;
92 else
93 last->next = next;
94 curr->next = next->next;
95 next->next = curr;
97 last = curr;
98 curr = curr->next;
100 } while(!done);
102 #endif
104 static int gather_info(void)
106 struct proc_info pi;
107 struct thread_info ti;
108 thread_time *tt;
109 int err;
110 uint32 cookie, cookie2;
112 // walk through each thread in the system
113 cookie = 0;
114 for(;;) {
115 err = _kern_proc_get_next_proc_info(&cookie, &pi);
116 if(err < 0)
117 break;
119 cookie2 = 0;
120 for(;;) {
121 err = _kern_thread_get_next_thread_info(&cookie2, pi.pid, &ti);
122 if(err < 0)
123 break;
125 tt = find_in_list(ti.id);
126 if(!tt) {
127 // create a new one
128 tt = malloc(sizeof(thread_time));
129 if(!tt)
130 return ERR_NO_MEMORY;
132 memset(&tt->info, 0, sizeof(struct thread_info));
134 insert_in_list(tt);
137 // save the last user and kernel time
138 tt->last_user_time = tt->info.user_time;
139 tt->last_kernel_time = tt->info.kernel_time;
141 // save the new data
142 memcpy(&tt->info, &ti, sizeof(ti));
144 // calculate the delta time
145 tt->delta_user_time = tt->info.user_time - tt->last_user_time;
146 tt->delta_kernel_time = tt->info.kernel_time - tt->last_kernel_time;
148 tt->touched = true;
152 // prune any untouched entries
153 prune_untouched();
155 // sort the entries
156 // sort_times();
158 return 0;
161 static int display_info(void)
163 thread_time *tt;
164 bigtime_t total_user = 0;
165 bigtime_t total_kernel = 0;
167 // clear and home the screen
168 printf("%c[2J%c[H", 0x1b, 0x1b);
170 // print the thread dump
171 printf(" tid pid pri usertime kerneltime name\n");
172 for(tt = times; tt; tt = tt->next) {
173 printf("%6d%6d%6d%12Ld%12Ld%32s\n",
174 tt->info.id, tt->info.owner_proc_id, tt->info.priority, tt->delta_user_time, tt->delta_kernel_time, tt->info.name);
175 total_user += tt->delta_user_time;
176 total_kernel += tt->delta_kernel_time;
178 printf("%18s%12Ld%12Ld\n", "total:", total_user, total_kernel);
180 return 0;
183 int main(int argc, char **argv)
185 int err;
187 for(;;) {
188 // gather data about each of the threads in the system
189 err = gather_info();
190 if(err < 0)
191 return err;
193 err = display_info();
194 if(err < 0)
195 return err;
197 usleep(1000000);