PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
thmon.c
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Copyright ps2dev - http://www.ps2dev.org
7# Licenced under Academic Free License version 2.0
8# Review ps2sdk README & LICENSE files for further details.
9*/
10
11#include "irx_imports.h"
12
13#include "thcommon.h"
14
15IRX_ID("Temporarily_Thread_monitor", 1, 3);
16// Based on the module from SCE SDK 3.1.0.
17
19{
20 volatile int m_start_stop_status;
21 struct thread *m_thread;
22 int m_sample_count;
23 // cppcheck-suppress unusedStructMember
24 int m_unused_c;
25 int m_barchart;
26 int m_verbose;
27};
28
30{
31 struct thread *m_thread_ptr;
32 int m_thread_id;
33 int m_flags;
34 iop_sys_clock_t m_old_clocks;
35 iop_sys_clock_t m_new_clocks;
36};
37
39{
40 iop_sys_clock_t m_target;
41 unsigned int m_alarm_id;
42 void *m_cb;
43 void *m_userptr;
44};
45
46static int CreateThmonThread(u32 attr, void (*thread)(void *arg), u32 priority, u32 stacksize, u32 option);
47static int do_get_thread_count();
48static void ThmonMonitorThread(void *arg);
49static void ThmonMainThread(void *arg);
50
51static const char *g_help_msg[] =
52 {
53 "\nsimple thread monitor program =====================================\n",
54 "-- thlist [-v] [-a] [<thid>] -- thread list\n",
55 "-- rdlist [-v] -- ready thread list\n",
56 "-- sllist [-v] -- sleeping thread list\n",
57 "-- dllist [-v] -- delayed thread list\n",
58 "-- rtlist [-v] [<times>] -- thread running time list\n",
59 "-- semlist [-w] [-v] -- semaphore list\n",
60 "-- evlist [-w] [-v] -- eventflag list\n",
61 "-- msglist -- messagebox list\n",
62 "-- vpllist -- Vpool list\n",
63 "-- fpllist -- Fpool list\n",
64 "-- almlist -- Alarm list\n",
65 "-- cpuwatch [-b] [-br] [-v] [<samples>] -- cpu time watching <samples/sec>\n",
66 "-- thwatch [-b] [-br] [-v] <thid> [<samples>] -- thread time watching <samples/sec>\n",
67 "-- freemem -- report free memory size\n",
68 "-- vblank <on/off> -- vblank interrupt on/off\n",
69 "-- / -- repeat last command\n",
70 NULL,
71};
72static const char *g_th_status_short = "000RunRdy333Wat555666777Sus999aaabbbWSudddeeefffDom???";
73static const char *g_th_wait_short = " SlDlSeEvMbVpFp ";
74static struct thread_context *g_ThbaseInternal;
75static int g_monitorThreadId;
76static int g_tty9_fd;
77static struct thmon_rtlist_item *g_rtlist_nondormant;
78static char g_progspace1[52];
79static char g_progspace2[52];
80static struct thmon_thcpuwatch_param g_thcpuwatch_info;
81static char g_PreviousCommand[208];
82static char g_CommandBuffer[200];
83
84int _start(int ac, char **av)
85{
86 int margen_val;
87 int main_thread_id;
88
89 margen_val = 10;
90 if (ac >= 2 && !strncmp(av[1], "-th=", 4)) {
91 margen_val = strtol(av[1] + 4, 0, 10) + 10;
92 printf("margen = %d\n", margen_val);
93 }
94 g_thcpuwatch_info.m_start_stop_status = 0;
95 g_tty9_fd = open("tty9:", 3);
96 g_ThbaseInternal = (struct thread_context *)GetThreadmanData();
97 main_thread_id = CreateThmonThread(
98 0x2000000u,
99 ThmonMainThread,
100 6u,
101 28 * (do_get_thread_count() + margen_val) + 3584,
102 0);
103 g_monitorThreadId = CreateThmonThread(0x2000000u, ThmonMonitorThread, 4u, 0x800u, 0);
104 if (main_thread_id <= 0 || g_monitorThreadId <= 0)
105 return 1;
106 StartThread(main_thread_id, 0);
107 return 0;
108}
109
110static int CreateThmonThread(u32 attr, void (*thread)(void *arg), u32 priority, u32 stacksize, u32 option)
111{
112 iop_thread_t thparam;
113
114 thparam.attr = attr;
115 thparam.thread = thread;
116 thparam.priority = priority;
117 thparam.stacksize = stacksize;
118 thparam.option = option;
119 return CreateThread(&thparam);
120}
121
122static int do_get_thread_count()
123{
124 struct thread *thread;
125 int i;
126 int state;
127
128 i = 0;
129 CpuSuspendIntr(&state);
130 list_for_each (thread, &g_ThbaseInternal->thread_list, thread_list) {
131 i += 1;
132 }
133 CpuResumeIntr(state);
134 return i;
135}
136
137static void PrintMessage(const char *msg)
138{
139 fdprintf(g_tty9_fd, "%s\n", msg);
140}
141
142static char *RemoveLeadingWhitespaces(char *str)
143{
144 for (; *str == ' ' || *str == '\t'; str += 1) {
145 *str = 0;
146 }
147 return str;
148}
149
150static char *GetEndOfString(char *str)
151{
152 for (; *str && *str != ' ' && *str != '\t'; str += 1)
153 ;
154 return str;
155}
156
157static void DisplayHelpMessage()
158{
159 int i;
160
161 for (i = 0; g_help_msg[i]; i += 1) {
162 fdprintf(g_tty9_fd, g_help_msg[i]);
163 if (i + 1 == 23 * ((i + 1) / 23) && g_help_msg[i + 1]) {
164 fdprintf(g_tty9_fd, " more ? ");
165 if (fdgetc(g_tty9_fd) != 'y') {
166 fdprintf(g_tty9_fd, "\n");
167 break;
168 }
169 fdprintf(g_tty9_fd, "\r");
170 }
171 }
172}
173
174static int do_parse_hex(char *str)
175{
176 int retres;
177
178 retres = 0;
179 for (; *str && isxdigit(*str); str += 1) {
180 retres *= 16;
181 retres += toupper(*str);
182 retres -= isdigit(*str) ? '0' : '7';
183 }
184 return retres;
185}
186
187static char *get_module_name_from_addr(unsigned int entry_addr)
188{
189 ModuleInfo_t *image_info;
190
191 for (image_info = GetLoadcoreInternalData()->image_info; image_info; image_info = image_info->next) {
192 if (entry_addr >= image_info->text_start && entry_addr < image_info->text_start + image_info->text_size)
193 return image_info->name;
194 }
195 return 0;
196}
197
198static void DisplayThreadInformation(struct thread *threadstruct, int is_verbose, int is_brief)
199{
200 if (is_brief)
201 fdprintf(g_tty9_fd, " ");
202 fdprintf(
203 g_tty9_fd,
204 "%3x %07x %08x %07x %.3s ",
205 threadstruct->tag.id,
206 MAKE_HANDLE(threadstruct),
207 threadstruct->attr,
208 threadstruct->option,
209 &g_th_status_short[3 * (char)threadstruct->status]);
210 fdprintf(
211 g_tty9_fd,
212 "%06x %06x %04x %06x %3d %3d",
213 threadstruct->entry,
214 threadstruct->stack_top,
215 threadstruct->stack_size,
216 threadstruct->gp,
217 (s16)threadstruct->priority,
218 (s16)threadstruct->init_priority);
219 if (is_brief) {
220 fdprintf(g_tty9_fd, "\n");
221 } else {
222 fdprintf(
223 g_tty9_fd,
224 " %c%c ",
225 g_th_wait_short[2 * (s16)threadstruct->wait_type],
226 g_th_wait_short[2 * (s16)threadstruct->wait_type + 1]);
227 switch ((s16)threadstruct->wait_type) {
228 case 1:
229 fdprintf(g_tty9_fd, "%7s%2x\n", "", threadstruct->wakeup_count);
230 break;
231 case 2:
232 fdprintf(g_tty9_fd, "%6x %2x\n", threadstruct->wait_usecs, threadstruct->wakeup_count);
233 break;
234 case 0:
235 default:
236 fdprintf(
237 g_tty9_fd,
238 "%07x%2x\n",
239 MAKE_HANDLE(threadstruct->wait_usecs),
240 threadstruct->wakeup_count);
241 break;
242 }
243 }
244 if (is_verbose) {
245 char *module_name_from_addr;
246
247 module_name_from_addr = get_module_name_from_addr((unsigned int)threadstruct->entry);
248 if (module_name_from_addr) {
249 if (is_brief)
250 fdprintf(g_tty9_fd, " ");
251 fdprintf(g_tty9_fd, " Name=%s\n", module_name_from_addr);
252 }
253 }
254 if (threadstruct->saved_regs && threadstruct->status != 16) {
255 if (is_brief)
256 fdprintf(g_tty9_fd, " ");
257 fdprintf(
258 g_tty9_fd,
259 " PC=%06x RA=%06x SP=%06x Context_addr/mask=%08x/%08x\n",
260 threadstruct->saved_regs->pc,
261 threadstruct->saved_regs->ra,
262 threadstruct->saved_regs->sp,
263 threadstruct->saved_regs,
264 threadstruct->saved_regs->unk);
265 }
266 if (is_verbose) {
267 unsigned int i;
268
269 for (i = 0; i < (threadstruct->stack_size / 4); i += 1) {
270 if (((u32 *)threadstruct->stack_top)[i] != 0xFFFFFFFF && ((u32 *)threadstruct->stack_top)[i] != 0x11111111)
271 break;
272 }
273 if (is_brief)
274 fdprintf(g_tty9_fd, " ");
275 fdprintf(g_tty9_fd, " Free_Stack_Size=%06x", i * 4);
276 fdprintf(
277 g_tty9_fd,
278 " I-preempt/T-preenmpt/release counts=%d,%d,%d\n",
279 threadstruct->irq_preemption_count,
280 threadstruct->thread_preemption_count,
281 threadstruct->release_count);
282 if (is_brief && threadstruct->wait_type == 4) {
283 fdprintf(g_tty9_fd, " ");
284 fdprintf(
285 g_tty9_fd,
286 " Event bitpattern, mode=0x%08x, 0x%x\n",
287 threadstruct->event_bits,
288 (s16)threadstruct->event_mode);
289 }
290 }
291}
292
293static void thlist_cmd_handler(char *cmdparam)
294{
295 char *cmdparam_cur;
296 int is_flag_v;
297 int is_flag_a;
298 int is_flag_i;
299 int is_hexval;
300 char *EndOfString;
301 struct thread *thread;
302 iop_thread_info_t thstatus;
303
304 is_flag_v = 0;
305 is_flag_a = 0;
306 is_flag_i = 0;
307 is_hexval = 0;
308 for (cmdparam_cur = cmdparam; *cmdparam_cur; cmdparam_cur = EndOfString) {
309 EndOfString = GetEndOfString(cmdparam_cur);
310 if (*EndOfString) {
311 *EndOfString = 0;
312 EndOfString = RemoveLeadingWhitespaces(EndOfString + 1);
313 }
314 if (!strcmp(cmdparam_cur, "-v"))
315 is_flag_v = 1;
316 if (!strcmp(cmdparam_cur, "-a"))
317 is_flag_a = 1;
318 if (!strcmp(cmdparam_cur, "-i"))
319 is_flag_i = 1;
320 if (*cmdparam_cur != '-')
321 is_hexval = do_parse_hex(cmdparam_cur);
322 }
323 if (is_hexval) {
324 if (is_hexval < g_ThbaseInternal->thread_id) {
325 list_for_each (thread, &g_ThbaseInternal->thread_list, thread_list) {
326 if (thread->tag.id == is_hexval) {
327 break;
328 }
329 }
330 if (!thread || thread->tag.id != is_hexval) {
331 fdprintf(g_tty9_fd, "thread #%d not found \n", is_hexval);
332 return;
333 }
334 is_hexval = MAKE_HANDLE(thread);
335 }
336 if (ReferThreadStatus(is_hexval, &thstatus) < 0) {
337 fdprintf(g_tty9_fd, "thid:%x not found \n", is_hexval);
338 return;
339 }
340 fdprintf(g_tty9_fd, " THID ATTR OPTION STS ENTRY STACK SSIZE GP CP IP WT WID WUC\n");
341 DisplayThreadInformation(
342 (struct thread *)HANDLE_PTR(is_hexval),
343 is_flag_v,
344 0);
345 } else {
346 fdprintf(g_tty9_fd, " THID ATTR OPTION STS ENTRY STACK SSIZE GP CP IP WT WID WUC\n");
347 list_for_each (thread, &g_ThbaseInternal->thread_list, thread_list) {
348 if (ReferThreadStatus(MAKE_HANDLE(thread), &thstatus) < 0) {
349 fdprintf(
350 g_tty9_fd,
351 "thid = %x not found \n",
352 MAKE_HANDLE(thread));
353 continue;
354 }
355 if ((is_flag_a || thstatus.status != 16) && (is_flag_i || thread != g_ThbaseInternal->idle_thread)) {
356 DisplayThreadInformation(thread, is_flag_v, 0);
357 }
358 }
359 }
360}
361
362static void do_rtlist_handle_clock(int is_flag_v_or_c)
363{
364 struct thread *thread;
365 char *module_name_from_addr;
366 iop_thread_info_t thstatus;
367 iop_sys_clock_t clks;
368 u32 sec_val;
369 u32 usec_val;
370
371 fdprintf(g_tty9_fd, " THID CLOCK SEC\n");
372 list_for_each (thread, &g_ThbaseInternal->thread_list, thread_list) {
373 if (ReferThreadStatus(MAKE_HANDLE(thread), &thstatus) < 0 || thstatus.status == 16) {
374 fdprintf(
375 g_tty9_fd,
376 "thid = %x not found \n",
377 (unsigned int)MAKE_HANDLE(thread));
378 continue;
379 }
380 clks.hi = thread->run_clocks_hi;
381 clks.lo = thread->run_clocks_lo;
382 SysClock2USec(&clks, &sec_val, &usec_val);
383 if (thread == g_ThbaseInternal->idle_thread) {
384 fdprintf(
385 g_tty9_fd,
386 " %08x_%08x %5d.%06d",
387 thread->run_clocks_hi,
388 thread->run_clocks_lo,
389 sec_val,
390 usec_val);
391 fdprintf(g_tty9_fd, " System Idle time\n");
392 } else {
393 fdprintf(
394 g_tty9_fd,
395 "%3x %07x %08x_%08x %5d.%06d",
396 thread->tag.id,
397 (unsigned int)MAKE_HANDLE(thread),
398 thread->run_clocks_hi,
399 thread->run_clocks_lo,
400 sec_val,
401 usec_val);
402 if (is_flag_v_or_c) {
403 module_name_from_addr = get_module_name_from_addr((unsigned int)thstatus.entry);
404 if (module_name_from_addr)
405 fdprintf(g_tty9_fd, " Name=%s", module_name_from_addr);
406 }
407 fdprintf(g_tty9_fd, "\n");
408 }
409 }
410 fdprintf(
411 g_tty9_fd,
412 " Total thread switch count = %d, comes out of idle count = %d\n",
413 g_ThbaseInternal->thread_switch_count,
414 g_ThbaseInternal->idle_thread->irq_preemption_count);
415}
416
417static void sys_clock_subtract(
418 const iop_sys_clock_t *pStart,
419 const iop_sys_clock_t *pEnd,
420 iop_sys_clock_t *pRet)
421{
422 iop_sys_clock_t diff;
423
424 diff.lo = pEnd->lo - pStart->lo;
425 diff.hi = pEnd->hi - pStart->hi - (pStart->lo > pEnd->lo);
426 memcpy(pRet, &diff, sizeof(diff));
427}
428
429static void do_rtlist_handle_priority(int is_flag_v_or_c, int int_value)
430{
431 struct thread *thread;
432 struct thread *curptr;
433 char *module_name_from_addr;
434 iop_sys_clock_t timebefore;
435 iop_sys_clock_t timeafter;
436 iop_sys_clock_t timeres;
437 u32 sec;
438 u32 usec;
439
440 g_rtlist_nondormant = __builtin_alloca(sizeof(struct thmon_rtlist_item) * do_get_thread_count());
441 for (; int_value > 0; int_value -= 1) {
442 struct thmon_rtlist_item *curelem1;
443 struct thmon_rtlist_item *curelem2;
444
445 curelem1 = g_rtlist_nondormant;
446 list_for_each (thread, &g_ThbaseInternal->thread_list, thread_list) {
447 curelem1->m_thread_ptr = 0;
448 if (thread->status != 16) {
449 curelem1->m_thread_ptr = thread;
450 curelem1->m_thread_id = thread->tag.id;
451 curelem1->m_old_clocks.hi = thread->run_clocks_hi;
452 curelem1->m_old_clocks.lo = thread->run_clocks_lo;
453 curelem1 += 1;
454 curelem1->m_thread_ptr = 0;
455 }
456 }
457 GetSystemTime(&timebefore);
458 DelayThread(1000000);
459 GetSystemTime(&timeafter);
460 for (curelem2 = g_rtlist_nondormant; curelem2->m_thread_ptr; curelem2 += 1) {
461 if (curelem2->m_thread_id == curelem2->m_thread_ptr->tag.id) {
462 curelem2->m_flags = 0;
463 curelem2->m_new_clocks.hi = curelem2->m_thread_ptr->run_clocks_hi;
464 curelem2->m_new_clocks.lo = curelem2->m_thread_ptr->run_clocks_lo;
465 } else {
466 curelem2->m_flags = -1;
467 }
468 }
469 sys_clock_subtract(&timeafter, &timebefore, &timeafter);
470 fdprintf(g_tty9_fd, " THID PRIO USE\n");
471 for (curelem2 = g_rtlist_nondormant; curelem2->m_thread_ptr; curelem2 += 1) {
472 if ((curelem2->m_flags & 0x80000000) != 0) {
473 continue;
474 }
475 curptr = curelem2->m_thread_ptr;
476 sys_clock_subtract(&curelem2->m_new_clocks, &curelem2->m_old_clocks, &timeres);
477 // Unofficial: use SysClock2USec
478 // TODO: giant magic math function timeafter, timeres
479 SysClock2USec(&timeafter, &sec, &usec);
480 if (curptr != g_ThbaseInternal->idle_thread) {
481 fdprintf(
482 g_tty9_fd,
483 "%3x %07x %3d %3d.%03d %%",
484 curptr->tag.id,
485 MAKE_HANDLE(curptr),
486 (s16)curptr->priority,
487 sec,
488 usec);
489 if (is_flag_v_or_c) {
490 module_name_from_addr = get_module_name_from_addr((unsigned int)curptr->entry);
491 if (module_name_from_addr)
492 fdprintf(g_tty9_fd, " Name=%s", module_name_from_addr);
493 }
494 fdprintf(g_tty9_fd, "\n");
495 DelayThread(400);
496 } else {
497 fdprintf(
498 g_tty9_fd,
499 " %6d/%6d/ %3d.%03d %%",
500 g_ThbaseInternal->thread_switch_count,
501 curptr->irq_preemption_count,
502 sec,
503 usec);
504 fdprintf(g_tty9_fd, " Total switch / comes out of idle / System Idle time\n");
505 }
506 }
507 }
508}
509
510static void rtlist_cmd_handler(char *cmdparam)
511{
512 char *cmdparam_cur;
513 int is_flag_v_or_c;
514 int int_value;
515 char *EndOfString;
516
517 is_flag_v_or_c = 0;
518 int_value = 0;
519 for (cmdparam_cur = cmdparam; *cmdparam_cur; cmdparam_cur = EndOfString) {
520 EndOfString = GetEndOfString(cmdparam_cur);
521 if (*EndOfString) {
522 *EndOfString = 0;
523 EndOfString = RemoveLeadingWhitespaces(EndOfString + 1);
524 }
525 if (!strcmp(cmdparam_cur, "-v"))
526 is_flag_v_or_c |= 1u;
527 if (!strcmp(cmdparam_cur, "-c"))
528 is_flag_v_or_c |= 2u;
529 if (*cmdparam_cur != '-')
530 int_value = strtol(cmdparam_cur, 0, 10);
531 }
532 if (int_value)
533 do_rtlist_handle_priority(is_flag_v_or_c, int_value);
534 else
535 do_rtlist_handle_clock(is_flag_v_or_c);
536}
537
538static char *do_output_progress_bar_newline(int curlen)
539{
540 int curlen_div_2000;
541
542 curlen_div_2000 = curlen / 2000;
543 strncpy(g_progspace1, "----+----+----+----+----+----+----+----+----+----+", curlen / 2000);
544 g_progspace1[curlen_div_2000] = '\n';
545 g_progspace1[curlen_div_2000 + 1] = '\0';
546 return g_progspace1;
547}
548
549static char *do_output_progress_bar_carriageret(int curlen)
550{
551 int curlen_div_2000;
552
553 curlen_div_2000 = curlen / 2000;
554 strncpy(g_progspace2, "----+----+----+----+----+----+----+----+----+----+", curlen / 2000);
555 strncpy(&g_progspace2[curlen_div_2000], " ", 50 - curlen_div_2000);
556 strcpy(&g_progspace2[50], "\r");
557 return g_progspace2;
558}
559
560static void ThmonMonitorThread(void *arg)
561{
562 int chrcnt;
563 int delayval;
564 struct thread *target_thread;
565 int math_magic_3;
566 iop_sys_clock_t sys_time_clks_2;
567 iop_sys_clock_t sys_time_clks_1;
568 iop_sys_clock_t target_thread_clks_2;
569 iop_sys_clock_t target_thread_clks_1;
570 iop_sys_clock_t this_thread_clks_2;
571 iop_sys_clock_t this_thread_clks_1;
572 iop_sys_clock_t tmp_time_clks_1;
573 iop_sys_clock_t tmp_time_clks_2;
574 struct thread *this_thread;
575 u32 sec;
576 u32 usec;
577 struct thmon_thcpuwatch_param *usrptr;
578
579 usrptr = (struct thmon_thcpuwatch_param *)arg;
580 chrcnt = 0;
581 delayval = 1000 * (1000 / usrptr->m_sample_count);
582 usrptr->m_start_stop_status = 1;
583 target_thread = usrptr->m_thread;
584 this_thread = (struct thread *)HANDLE_PTR(GetThreadId());
585 this_thread_clks_2.lo = 0;
586 this_thread_clks_2.hi = 0;
587 while (usrptr->m_start_stop_status != 2) {
588 if (target_thread) {
589 target_thread_clks_1.hi = target_thread->run_clocks_hi;
590 target_thread_clks_1.lo = target_thread->run_clocks_lo;
591 DelayThread(delayval);
592 GetSystemTime(&sys_time_clks_1);
593 sys_clock_subtract(
594 &sys_time_clks_1,
595 &sys_time_clks_2,
596 &tmp_time_clks_1);
597 sys_time_clks_2 = sys_time_clks_1;
598 target_thread_clks_2.hi = target_thread->run_clocks_hi;
599 target_thread_clks_2.lo = target_thread->run_clocks_lo;
600 this_thread_clks_1.hi = this_thread->run_clocks_hi;
601 this_thread_clks_1.lo = this_thread->run_clocks_lo;
602 sys_clock_subtract(
603 &this_thread_clks_1,
604 &this_thread_clks_2,
605 &this_thread_clks_2);
606 sys_clock_subtract(
607 &tmp_time_clks_1,
608 &this_thread_clks_2,
609 &tmp_time_clks_1);
610 this_thread_clks_2 = this_thread_clks_1;
611 sys_clock_subtract(
612 &target_thread_clks_2,
613 &target_thread_clks_1,
614 &tmp_time_clks_2);
615 // Unofficial: use SysClock2USec
616 // TODO: giant magic math function tmp_time_clks_1, tmp_time_clks_2
617 SysClock2USec(&tmp_time_clks_1, &sec, &usec);
618 switch (usrptr->m_barchart) {
619 case 0:
620 Kprintf("%3d.%03d %07x", sec, usec, target_thread->saved_regs->pc);
621 if (usrptr->m_verbose) {
622 Kprintf(
623 " %6d/%6d/%6d ",
624 target_thread->irq_preemption_count,
625 target_thread->thread_preemption_count,
626 target_thread->release_count);
627 Kprintf("%c", (chrcnt <= 0) ? ' ' : '\n');
628 ++chrcnt;
629 if (chrcnt >= 2)
630 chrcnt = 0;
631 } else {
632 Kprintf("%c", (chrcnt < 4) ? ' ' : '\n');
633 ++chrcnt;
634 if (chrcnt >= 5)
635 chrcnt = 0;
636 }
637 break;
638 case 1:
639 case 2:
640 Kprintf(
641 "%3d.%03d:%s",
642 sec,
643 usec,
644 (usrptr->m_barchart == 1) ? do_output_progress_bar_newline(sec * 1000 + usec) : do_output_progress_bar_carriageret(sec * 1000 + usec));
645 break;
646 default:
647 break;
648 }
649 } else {
650 target_thread_clks_1.hi = g_ThbaseInternal->idle_thread->run_clocks_hi;
651 target_thread_clks_1.lo = g_ThbaseInternal->idle_thread->run_clocks_lo;
652 GetSystemTime(&sys_time_clks_2);
653 DelayThread(delayval);
654 GetSystemTime(&sys_time_clks_1);
655 target_thread_clks_2.hi = g_ThbaseInternal->idle_thread->run_clocks_hi;
656 target_thread_clks_2.lo = g_ThbaseInternal->idle_thread->run_clocks_lo;
657 sys_clock_subtract(
658 &sys_time_clks_1,
659 &sys_time_clks_2,
660 &tmp_time_clks_1);
661 sys_clock_subtract(
662 &target_thread_clks_2,
663 &target_thread_clks_1,
664 &tmp_time_clks_2);
665 // Unofficial: use SysClock2USec
666 // TODO: giant magic math function tmp_time_clks_1, tmp_time_clks_2
667 SysClock2USec(&tmp_time_clks_1, &sec, &usec);
668 math_magic_3 = 100000 - (sec * 1000 + usec);
669 switch (usrptr->m_barchart) {
670 case 0:
671 Kprintf("%3d.%03d", math_magic_3 / 1000, math_magic_3 % 1000);
672 if (usrptr->m_verbose) {
673 Kprintf(
674 " %6d/%6d%s",
675 g_ThbaseInternal->thread_switch_count,
676 g_ThbaseInternal->idle_thread->irq_preemption_count,
677 (chrcnt < 2) ? " " : "\n");
678 ++chrcnt;
679 if (chrcnt >= 3)
680 chrcnt = 0;
681 } else {
682 Kprintf((chrcnt < 8) ? " " : "\n");
683 ++chrcnt;
684 if (chrcnt >= 9)
685 chrcnt = 0;
686 }
687 break;
688 case 1:
689 case 2:
690 Kprintf(
691 "%3d.%03d:%s",
692 math_magic_3 / 1000,
693 math_magic_3 % 1000,
694 (usrptr->m_barchart == 1) ? do_output_progress_bar_newline(math_magic_3) : do_output_progress_bar_carriageret(math_magic_3));
695 break;
696 default:
697 break;
698 }
699 }
700 }
701 usrptr->m_start_stop_status = 0;
702}
703
704static void do_stop_current_thcpuwatch()
705{
706 if (!g_thcpuwatch_info.m_start_stop_status) {
707 return;
708 }
709 g_thcpuwatch_info.m_start_stop_status = 2;
710 while (g_thcpuwatch_info.m_start_stop_status) {
711 DelayThread(1000);
712 }
713}
714
715static void thwatch_cmd_handler(char *cmdparam)
716{
717 char *cmdparam_cur;
718 int is_flag_b_or_br;
719 int integer_value;
720 int hex_value;
721 int is_flag_v;
722 char *EndOfString;
723
724 iop_thread_info_t thstatus;
725
726 is_flag_b_or_br = 0;
727 integer_value = 10;
728 hex_value = 0;
729 is_flag_v = 0;
730 for (cmdparam_cur = cmdparam; *cmdparam_cur; cmdparam_cur = EndOfString) {
731 EndOfString = GetEndOfString(cmdparam_cur);
732 if (*EndOfString) {
733 *EndOfString = 0;
734 EndOfString = RemoveLeadingWhitespaces(EndOfString + 1);
735 }
736 if (!strcmp(cmdparam_cur, "-b"))
737 is_flag_b_or_br = 1;
738 if (!strcmp(cmdparam_cur, "-br"))
739 is_flag_b_or_br = 2;
740 if (!strcmp(cmdparam_cur, "-v"))
741 is_flag_v = 1;
742 if (*cmdparam_cur != '-') {
743 if (hex_value)
744 integer_value = strtol(cmdparam_cur, 0, 10);
745 else
746 hex_value = do_parse_hex(cmdparam_cur);
747 }
748 }
749 do_stop_current_thcpuwatch();
750 if (!hex_value) {
751 return;
752 }
753 if (hex_value < g_ThbaseInternal->thread_id) {
754 struct thread *thread;
755
756 list_for_each (thread, &g_ThbaseInternal->thread_list, thread_list) {
757 if (thread->tag.id == hex_value)
758 break;
759 }
760 if (!thread || thread->tag.id != hex_value) {
761 fdprintf(g_tty9_fd, "thread #%d not found \n", hex_value);
762 return;
763 }
764 hex_value = MAKE_HANDLE(thread);
765 }
766 g_thcpuwatch_info.m_barchart = is_flag_b_or_br;
767 g_thcpuwatch_info.m_sample_count = integer_value;
768 g_thcpuwatch_info.m_verbose = is_flag_v;
769 if (hex_value <= 0 || ReferThreadStatus(hex_value, &thstatus)) {
770 fdprintf(g_tty9_fd, "thid:%x not found \n", hex_value);
771 } else if (integer_value > 0) {
772 g_thcpuwatch_info.m_thread = (struct thread *)HANDLE_PTR(hex_value);
773 fdprintf(g_tty9_fd, "Thread %x time watching and print to ITTYK\n", hex_value);
774 StartThread(g_monitorThreadId, &g_thcpuwatch_info);
775 }
776}
777
778static void cpuwatch_cmd_handler(char *cmdparam)
779{
780 char *cmdparam_cur;
781 int is_flag_b_or_br;
782 int int_value;
783 int is_flag_v;
784 char *EndOfString;
785
786 is_flag_b_or_br = 0;
787 int_value = 10;
788 is_flag_v = 0;
789 for (cmdparam_cur = cmdparam; *cmdparam_cur; cmdparam_cur = EndOfString) {
790 EndOfString = GetEndOfString(cmdparam_cur);
791 if (*EndOfString) {
792 *EndOfString = 0;
793 EndOfString = RemoveLeadingWhitespaces(EndOfString + 1);
794 }
795 if (!strcmp(cmdparam_cur, "-b"))
796 is_flag_b_or_br = 1;
797 if (!strcmp(cmdparam_cur, "-br"))
798 is_flag_b_or_br = 2;
799 if (!strcmp(cmdparam_cur, "-v"))
800 is_flag_v = 1;
801 if (*cmdparam_cur != '-')
802 int_value = strtol(cmdparam_cur, 0, 10);
803 }
804 do_stop_current_thcpuwatch();
805 if (int_value > 0) {
806 g_thcpuwatch_info.m_barchart = is_flag_b_or_br;
807 g_thcpuwatch_info.m_sample_count = int_value;
808 g_thcpuwatch_info.m_verbose = is_flag_v;
809 g_thcpuwatch_info.m_thread = 0;
810 fdprintf(g_tty9_fd, "CPU time watching and print to ITTYK\n");
811 StartThread(g_monitorThreadId, &g_thcpuwatch_info);
812 }
813}
814
815static void rdlist_cmd_handler(char *cmdparam)
816{
817 char *cmdparam_cur;
818 int is_flag_v;
819 int is_flag_i;
820 char *EndOfString;
821 int i;
822 struct thread *thread;
823 iop_thread_info_t thstatus;
824
825 is_flag_v = 0;
826 is_flag_i = 0;
827 for (cmdparam_cur = cmdparam; *cmdparam_cur; cmdparam_cur = EndOfString) {
828 EndOfString = GetEndOfString(cmdparam_cur);
829 if (*EndOfString) {
830 *EndOfString = 0;
831 EndOfString = RemoveLeadingWhitespaces(EndOfString + 1);
832 }
833 if (!strcmp(cmdparam_cur, "-v"))
834 is_flag_v = 1;
835 if (!strcmp(cmdparam_cur, "-i"))
836 is_flag_i = 1;
837 }
838 fdprintf(g_tty9_fd, " THID ATTR OPTION STS ENTRY STACK SSIZE GP CP IP WT WID WUC\n");
839 for (i = 1; i < (is_flag_i + 127); i += 1) {
840 if (list_empty(&g_ThbaseInternal->ready_queue[i])) {
841 continue;
842 }
843 list_for_each (thread, &g_ThbaseInternal->ready_queue[i], queue) {
844 if (!ReferThreadStatus(MAKE_HANDLE(thread), &thstatus))
845 DisplayThreadInformation(thread, is_flag_v, 0);
846 }
847 }
848}
849
850static void sllist_cmd_handler(char *cmdparam)
851{
852 char *cmdparam_cur;
853 int is_flag_v;
854 char *EndOfString;
855 struct thread *thread;
856 iop_thread_info_t thstatus;
857
858 is_flag_v = 0;
859 for (cmdparam_cur = cmdparam; *cmdparam_cur; cmdparam_cur = EndOfString) {
860 EndOfString = GetEndOfString(cmdparam_cur);
861 if (*EndOfString) {
862 *EndOfString = 0;
863 EndOfString = RemoveLeadingWhitespaces(EndOfString + 1);
864 }
865 if (!strcmp(cmdparam_cur, "-v"))
866 is_flag_v = 1;
867 }
868 fdprintf(g_tty9_fd, " THID ATTR OPTION STS ENTRY STACK SSIZE GP CP IP WT WID WUC\n");
869 list_for_each (thread, &g_ThbaseInternal->sleep_queue, queue) {
870 if (ReferThreadStatus(MAKE_HANDLE(thread), &thstatus) < 0) {
871 fdprintf(g_tty9_fd, "thid = %x not found \n", MAKE_HANDLE(thread));
872 continue;
873 }
874 if (thread != g_ThbaseInternal->idle_thread)
875 DisplayThreadInformation(thread, is_flag_v, 0);
876 }
877}
878
879static void dlist_print_thread_info(struct thread *threadstruct, int is_verbose)
880{
881 fdprintf(
882 g_tty9_fd,
883 "%3x %07x %08x %07x %.3s ",
884 threadstruct->tag.id,
885 MAKE_HANDLE(threadstruct),
886 threadstruct->attr,
887 threadstruct->option,
888 &g_th_status_short[3 * (char)threadstruct->status]);
889 fdprintf(
890 g_tty9_fd,
891 "%06x %06x %04x %06x %3d %3d %d\n",
892 threadstruct->entry,
893 threadstruct->stack_top,
894 threadstruct->stack_size,
895 threadstruct->gp,
896 (s16)threadstruct->priority,
897 (s16)threadstruct->init_priority,
898 threadstruct->wait_usecs);
899 if (is_verbose) {
900 char *module_name_from_addr;
901
902 module_name_from_addr = get_module_name_from_addr((unsigned int)threadstruct->entry);
903 if (module_name_from_addr)
904 fdprintf(g_tty9_fd, " Name=%s\n", module_name_from_addr);
905 }
906 if (threadstruct->saved_regs && threadstruct->status != 16)
907 fdprintf(
908 g_tty9_fd,
909 " PC=%06x RA=%06x SP=%06x Context_addr/mask=%08x/%08x\n",
910 threadstruct->saved_regs->pc,
911 threadstruct->saved_regs->ra,
912 threadstruct->saved_regs->sp,
913 threadstruct->saved_regs,
914 threadstruct->saved_regs->unk);
915 if (is_verbose) {
916 unsigned int i;
917
918 for (i = 0; i < (threadstruct->stack_size / 4); i += 1) {
919 if (((u32 *)threadstruct->stack_top)[i] != 0xFFFFFFFF && ((u32 *)threadstruct->stack_top)[i] != 0x11111111)
920 break;
921 }
922 fdprintf(g_tty9_fd, " Free_Stack_Size=%06x\n", i * 4);
923 }
924}
925
926static void dllist_cmd_handler(char *cmdparam)
927{
928 char *cmdparam_cur;
929 int is_flag_v;
930 char *EndOfString;
931 struct thread *thread;
932 iop_thread_info_t thstatus;
933
934 is_flag_v = 0;
935 for (cmdparam_cur = cmdparam; *cmdparam_cur; cmdparam_cur = EndOfString) {
936 EndOfString = GetEndOfString(cmdparam_cur);
937 if (*EndOfString) {
938 *EndOfString = 0;
939 EndOfString = RemoveLeadingWhitespaces(EndOfString + 1);
940 }
941 if (!strcmp(cmdparam_cur, "-v"))
942 is_flag_v = 1;
943 }
944 fdprintf(g_tty9_fd, " THID ATTR OPTION STS ENTRY STACK SSIZE GP CP IP USEC\n");
945 list_for_each (thread, &g_ThbaseInternal->delay_queue, queue) {
946 if (ReferThreadStatus(MAKE_HANDLE(thread), &thstatus) < 0) {
947 fdprintf(g_tty9_fd, "thid = %x not found \n", MAKE_HANDLE(thread));
948 continue;
949 }
950 if (thread != g_ThbaseInternal->idle_thread)
951 dlist_print_thread_info(thread, is_flag_v);
952 }
953}
954
955static void ShowSemList(char *cmdparam)
956{
957 char *cmdparam_cur;
958 int is_flag_v_count;
959 int is_flag_w_count;
960 char *EndOfString;
961 struct semaphore *sema;
962 struct thread *waiter;
963 iop_sema_info_t semastatus;
964 iop_thread_info_t thstatus;
965
966 is_flag_v_count = 0;
967 is_flag_w_count = 0;
968 for (cmdparam_cur = cmdparam; *cmdparam_cur; cmdparam_cur = EndOfString) {
969 EndOfString = GetEndOfString(cmdparam_cur);
970 if (*EndOfString) {
971 *EndOfString = 0;
972 EndOfString = RemoveLeadingWhitespaces(EndOfString + 1);
973 }
974 if (!strcmp(cmdparam_cur, "-v"))
975 ++is_flag_v_count;
976 if (!strcmp(cmdparam_cur, "-w"))
977 ++is_flag_w_count;
978 }
979 if (list_empty(&g_ThbaseInternal->semaphore)) {
980 return;
981 }
982 fdprintf(g_tty9_fd, " SEMID ATTR OPTION iCnt cCnt mCnt waitThreads\n");
983 list_for_each (sema, &g_ThbaseInternal->semaphore, sema_list) {
984 if (ReferSemaStatus(MAKE_HANDLE(sema), &semastatus) < 0) {
985 continue;
986 }
987 if (semastatus.numWaitThreads > 0 || !is_flag_w_count) {
988 fdprintf(
989 g_tty9_fd,
990 "%3x %07x %08x %08x %05d %5d %5d %5d\n",
991 sema->tag.id,
992 MAKE_HANDLE(sema),
993 semastatus.attr,
994 semastatus.option,
995 semastatus.initial,
996 semastatus.current,
997 semastatus.max,
998 semastatus.numWaitThreads);
999 }
1000 if (semastatus.numWaitThreads > 0 && is_flag_w_count) {
1001 fdprintf(g_tty9_fd, " THID ATTR OPTION STS ENTRY STACK SSIZE GP CP IP\n");
1002 list_for_each_safe (waiter, &sema->event.waiters, queue) {
1003 ReferThreadStatus(MAKE_HANDLE(waiter), &thstatus);
1004 DisplayThreadInformation(waiter, is_flag_v_count, 1);
1005 }
1006 }
1007 }
1008}
1009
1010static void ShowEventFlagList(char *cmdparam)
1011{
1012 char *cmdparam_cur;
1013 int is_flag_v_count;
1014 int is_flag_w_count;
1015 char *EndOfString;
1016 struct event_flag *evf;
1017 struct thread *waiter;
1018 iop_event_info_t efstatus;
1019 iop_thread_info_t thstatus;
1020
1021 is_flag_v_count = 0;
1022 is_flag_w_count = 0;
1023 for (cmdparam_cur = cmdparam; *cmdparam_cur; cmdparam_cur = EndOfString) {
1024 EndOfString = GetEndOfString(cmdparam_cur);
1025 if (*EndOfString) {
1026 *EndOfString = 0;
1027 EndOfString = RemoveLeadingWhitespaces(EndOfString + 1);
1028 }
1029 if (!strcmp(cmdparam_cur, "-v"))
1030 ++is_flag_v_count;
1031 if (!strcmp(cmdparam_cur, "-w"))
1032 ++is_flag_w_count;
1033 }
1034 if (list_empty(&g_ThbaseInternal->event_flag)) {
1035 return;
1036 }
1037 fdprintf(g_tty9_fd, " EVID ATTR OPTION iPattern cPattern waitThreads\n");
1038 list_for_each (evf, &g_ThbaseInternal->event_flag, evf_list) {
1039 if (ReferEventFlagStatus(MAKE_HANDLE(evf), &efstatus) < 0) {
1040 continue;
1041 }
1042 if (efstatus.numThreads > 0 || !is_flag_w_count) {
1043 fdprintf(
1044 g_tty9_fd,
1045 "%3x %07x %08x %08x %08x %08x %5d\n",
1046 evf->tag.id,
1047 MAKE_HANDLE(evf),
1048 efstatus.attr,
1049 efstatus.option,
1050 efstatus.initBits,
1051 efstatus.currBits,
1052 efstatus.numThreads);
1053 }
1054 if (efstatus.numThreads > 0 && is_flag_w_count) {
1055 fdprintf(g_tty9_fd, " THID ATTR OPTION STS ENTRY STACK SSIZE GP CP IP\n");
1056 list_for_each_safe (waiter, &evf->event.waiters, queue) {
1057 ReferThreadStatus(MAKE_HANDLE(waiter), &thstatus);
1058 DisplayThreadInformation(waiter, is_flag_v_count, 1);
1059 }
1060 }
1061 }
1062}
1063
1064static void ShowMsgbxList()
1065{
1066 struct mbox *mbx;
1067 iop_mbx_status_t mbxstatus;
1068
1069 if (list_empty(&g_ThbaseInternal->mbox)) {
1070 return;
1071 }
1072 fdprintf(g_tty9_fd, " MSGID ATTR OPTION waitThreads messages\n");
1073 list_for_each (mbx, &g_ThbaseInternal->mbox, mbox_list) {
1074 ReferMbxStatus(MAKE_HANDLE(mbx), &mbxstatus);
1075 fdprintf(
1076 g_tty9_fd,
1077 "%3x %07x %08x %08x %5d %5d\n",
1078 mbx->tag.id,
1079 MAKE_HANDLE(mbx),
1080 mbxstatus.attr,
1081 mbxstatus.option,
1082 mbxstatus.numWaitThreads,
1083 mbxstatus.numMessage);
1084 }
1085}
1086
1087static void ShowVplList()
1088{
1089 struct vpool *vpl;
1090 iop_vpl_info_t vplstatus;
1091
1092 if (list_empty(&g_ThbaseInternal->vpool)) {
1093 return;
1094 }
1095 fdprintf(g_tty9_fd, " VPLID ATTR OPTION Size Free waitThreads\n");
1096 list_for_each (vpl, &g_ThbaseInternal->vpool, vpl_list) {
1097 ReferVplStatus(MAKE_HANDLE(vpl), &vplstatus);
1098 fdprintf(
1099 g_tty9_fd,
1100 "%3x %07x %08x %08x %06x %06x %5d\n",
1101 vpl->tag.id,
1102 MAKE_HANDLE(vpl),
1103 vplstatus.attr,
1104 vplstatus.option,
1105 vplstatus.size,
1106 vplstatus.freeSize,
1107 vplstatus.numWaitThreads);
1108 }
1109}
1110
1111static void ShowFplList()
1112{
1113 struct fpool *fpl;
1114 iop_fpl_info_t fplstatus;
1115
1116 if (list_empty(&g_ThbaseInternal->fpool)) {
1117 return;
1118 }
1119 fdprintf(g_tty9_fd, " FPLID ATTR OPTION BlkSIze AllBlocks FreeSize waitThreads\n");
1120 list_for_each (fpl, &g_ThbaseInternal->fpool, fpl_list) {
1121 ReferFplStatus(MAKE_HANDLE(fpl), &fplstatus);
1122 fdprintf(
1123 g_tty9_fd,
1124 "%3x %07x %08x %08x %06x %06x %06x %5d\n",
1125 fpl->tag.id,
1126 MAKE_HANDLE(fpl),
1127 fplstatus.attr,
1128 fplstatus.option,
1129 fplstatus.blockSize,
1130 fplstatus.numBlocks,
1131 fplstatus.freeBlocks,
1132 fplstatus.numWaitThreads);
1133 }
1134}
1135
1136static void DumpReadyQueue()
1137{
1138 struct thread *thread;
1139 int i;
1140 int state;
1141
1142 fdprintf(g_tty9_fd, "ready queue ----\n");
1143 for (i = 0; i < 127; i += 1) {
1144 if (list_empty(&g_ThbaseInternal->ready_queue[i])) {
1145 continue;
1146 }
1147 CpuSuspendIntr(&state);
1148 fdprintf(g_tty9_fd, " %3d:%x ", i, &g_ThbaseInternal->ready_queue[i]);
1149 list_for_each (thread, &g_ThbaseInternal->ready_queue[i], queue)
1150 fdprintf(g_tty9_fd, " %d(%x) ", thread->tag.id, thread);
1151 fdprintf(g_tty9_fd, "\n");
1152 CpuResumeIntr(state);
1153 }
1154 fdprintf(g_tty9_fd, "ready map = ");
1155 for (i = 0; i < 4; i += 1) {
1156 fdprintf(g_tty9_fd, "%08x ", g_ThbaseInternal->queue_map[i]);
1157 }
1158 fdprintf(g_tty9_fd, "\n");
1159}
1160
1161static void ToggleThswdisp(const char *cmdparam)
1162{
1163 if (!strcmp(cmdparam, "on"))
1164 g_ThbaseInternal->debug_flags |= 1u;
1165 if (!strcmp(cmdparam, "off"))
1166 g_ThbaseInternal->debug_flags &= ~1u;
1167 if (isdigit(*cmdparam))
1168 g_ThbaseInternal->debug_flags = strtol(cmdparam, 0, 10);
1169}
1170
1171static void ToggleThLED(const char *cmdparam)
1172{
1173 if (!strcmp(cmdparam, "on"))
1174 g_ThbaseInternal->debug_flags |= 0x20u;
1175 if (!strcmp(cmdparam, "off"))
1176 g_ThbaseInternal->debug_flags &= ~0x20u;
1177 if (isdigit(*cmdparam))
1178 g_ThbaseInternal->debug_flags = strtol(cmdparam, 0, 10);
1179}
1180
1181static void ToggleWarnDisp(const char *cmdparam)
1182{
1183 if (!strcmp(cmdparam, "on"))
1184 g_ThbaseInternal->debug_flags |= 8u;
1185 if (!strcmp(cmdparam, "off"))
1186 g_ThbaseInternal->debug_flags &= ~8u;
1187 if (isdigit(*cmdparam))
1188 g_ThbaseInternal->debug_flags = strtol(cmdparam, 0, 10);
1189}
1190
1191static void DumpThreads()
1192{
1193 struct thread *thread;
1194
1195 fdprintf(g_tty9_fd, "===============================\n");
1196 fdprintf(g_tty9_fd, "tcb list ----\n");
1197 list_for_each (thread, &g_ThbaseInternal->thread_list, thread_list) {
1198 fdprintf(
1199 g_tty9_fd,
1200 " %d: tcb=%x sts=0x%x pri=%d ",
1201 thread->tag.id,
1202 thread,
1203 (char)thread->status,
1204 (s16)thread->priority);
1205 if ((char)thread->status == 4)
1206 fdprintf(g_tty9_fd, "wType = %x:%x ", (s16)thread->wait_type, thread->wait_usecs);
1207 if ((char)thread->status != 1)
1208 fdprintf(g_tty9_fd, "contx=%x sp=%x", thread->saved_regs, thread->saved_regs->sp);
1209 fdprintf(g_tty9_fd, "\n");
1210 }
1211 fdprintf(g_tty9_fd, "sleep list ----\n");
1212 if (list_empty(&g_ThbaseInternal->sleep_queue)) {
1213 return;
1214 }
1215 fdprintf(g_tty9_fd, " %x: ", &g_ThbaseInternal->sleep_queue);
1216 list_for_each (thread, &g_ThbaseInternal->sleep_queue, queue) {
1217 fdprintf(g_tty9_fd, " %d(%x) ", thread->tag.id, thread);
1218 }
1219 fdprintf(g_tty9_fd, "\n");
1220}
1221
1222static void ShowAlarmList()
1223{
1224 struct thmon_almlist_item *alarm_ents;
1225 int alarm_cnt;
1226 struct alarm *alarm;
1227 int i;
1228 int state;
1229
1230 alarm_ents = 0;
1231 CpuSuspendIntr(&state);
1232 alarm_cnt = 0;
1233 if (!list_empty(&g_ThbaseInternal->alarm)) {
1234 list_for_each (alarm, &g_ThbaseInternal->alarm, alarm_list) {
1235 alarm_cnt += 1;
1236 }
1237 alarm_ents = __builtin_alloca(alarm_cnt * sizeof(struct thmon_almlist_item));
1238 i = 0;
1239 list_for_each (alarm, &g_ThbaseInternal->alarm, alarm_list) {
1240 alarm_ents[i].m_alarm_id = alarm->tag.id;
1241 alarm_ents[i].m_target.lo = alarm->target;
1242 alarm_ents[i].m_target.hi = alarm->target >> 32;
1243 alarm_ents[i].m_cb = alarm->cb;
1244 alarm_ents[i].m_userptr = alarm->userptr;
1245 i += 1;
1246 }
1247 }
1248 CpuResumeIntr(state);
1249 fdprintf(g_tty9_fd, " NUM TIME HANDLER COMMON\n");
1250 for (i = 0; i < alarm_cnt; i += 1) {
1251 fdprintf(
1252 g_tty9_fd,
1253 "%3x %08x_%08x %06x, %08x\n",
1254 alarm_ents[i].m_alarm_id,
1255 alarm_ents[i].m_target.hi,
1256 alarm_ents[i].m_target.lo,
1257 alarm_ents[i].m_cb,
1258 alarm_ents[i].m_userptr);
1259 }
1260}
1261
1262static void freemem_cmd_handler()
1263{
1264 u32 TotalFreeMemSize;
1265
1266 TotalFreeMemSize = QueryTotalFreeMemSize();
1267 fdprintf(
1268 g_tty9_fd,
1269 "IOP system memory 0x%x(%d) byte free, Max free block size 0x%x\n",
1270 TotalFreeMemSize,
1271 TotalFreeMemSize,
1272 QueryMaxFreeMemSize());
1273}
1274
1275static void ThmonMainThread(void *arg)
1276{
1277 char *cmdbufsrc;
1278 char *cmdbufdst;
1279 char *cmdbuf_trim;
1280 char *cmdparam;
1281
1282 (void)arg;
1283
1284 fdprintf(g_tty9_fd, "\n\n========= simple thread monitor program =========\n");
1285 fdprintf(g_tty9_fd, "help command is 'help'\n");
1286 g_PreviousCommand[0] = 0;
1287 for (;;) {
1288 fdprintf(g_tty9_fd, " > ");
1289 if (!fdgets(g_CommandBuffer, g_tty9_fd))
1290 break;
1291 PrintMessage(g_CommandBuffer);
1292 if (!strlen(g_CommandBuffer))
1293 continue;
1294 if (!strcmp(g_CommandBuffer, "/")) {
1295 cmdbufsrc = g_PreviousCommand;
1296 cmdbufdst = g_CommandBuffer;
1297 } else {
1298 cmdbufsrc = g_CommandBuffer;
1299 cmdbufdst = g_PreviousCommand;
1300 }
1301 strcpy(cmdbufdst, cmdbufsrc);
1302 cmdbuf_trim = RemoveLeadingWhitespaces(g_CommandBuffer);
1303 cmdparam = RemoveLeadingWhitespaces(GetEndOfString(cmdbuf_trim));
1304 if (*cmdbuf_trim == '#')
1305 continue;
1306 if (!strncmp("quit", cmdbuf_trim, strlen(cmdbuf_trim)))
1307 break;
1308 else if (!strncmp("?", cmdbuf_trim, strlen(cmdbuf_trim)) || !strncmp("help", cmdbuf_trim, strlen(cmdbuf_trim)))
1309 DisplayHelpMessage();
1310 else if (!strncmp("thlist", cmdbuf_trim, strlen(cmdbuf_trim)))
1311 thlist_cmd_handler(cmdparam);
1312 else if (!strncmp("rdlist", cmdbuf_trim, strlen(cmdbuf_trim)))
1313 rdlist_cmd_handler(cmdparam);
1314 else if (!strncmp("sllist", cmdbuf_trim, strlen(cmdbuf_trim)))
1315 sllist_cmd_handler(cmdparam);
1316 else if (!strncmp("dllist", cmdbuf_trim, strlen(cmdbuf_trim)))
1317 dllist_cmd_handler(cmdparam);
1318 else if (!strncmp("rtlist", cmdbuf_trim, strlen(cmdbuf_trim)))
1319 rtlist_cmd_handler(cmdparam);
1320 else if (!strncmp("semlist", cmdbuf_trim, strlen(cmdbuf_trim)))
1321 ShowSemList(cmdparam);
1322 else if (!strncmp("evlist", cmdbuf_trim, strlen(cmdbuf_trim)))
1323 ShowEventFlagList(cmdparam);
1324 else if (!strncmp("msglist", cmdbuf_trim, strlen(cmdbuf_trim)))
1325 ShowMsgbxList();
1326 else if (!strncmp("vpllist", cmdbuf_trim, strlen(cmdbuf_trim)))
1327 ShowVplList();
1328 else if (!strncmp("fpllist", cmdbuf_trim, strlen(cmdbuf_trim)))
1329 ShowFplList();
1330 else if (!strncmp("almlist", cmdbuf_trim, strlen(cmdbuf_trim)))
1331 ShowAlarmList();
1332 else if (!strncmp("freemem", cmdbuf_trim, strlen(cmdbuf_trim)))
1333 freemem_cmd_handler();
1334 else if (!strncmp("cpuwatch", cmdbuf_trim, strlen(cmdbuf_trim)))
1335 cpuwatch_cmd_handler(cmdparam);
1336 else if (!strncmp("thwatch", cmdbuf_trim, strlen(cmdbuf_trim)))
1337 thwatch_cmd_handler(cmdparam);
1338 else if (!strncmp("thswdisp", cmdbuf_trim, strlen(cmdbuf_trim)))
1339 ToggleThswdisp(cmdparam);
1340 else if (!strncmp("thled", cmdbuf_trim, strlen(cmdbuf_trim)))
1341 ToggleThLED(cmdparam);
1342 else if (!strncmp("warndisp", cmdbuf_trim, strlen(cmdbuf_trim)))
1343 ToggleWarnDisp(cmdparam);
1344 else if (!strncmp("dumpthread", cmdbuf_trim, strlen(cmdbuf_trim)))
1345 DumpThreads();
1346 else if (!strncmp("dumpready", cmdbuf_trim, strlen(cmdbuf_trim)))
1347 DumpReadyQueue();
1348 else
1349 fdprintf(g_tty9_fd, " ?? \n");
1350 }
1351}
int CpuResumeIntr(int state)
Definition intrman.c:227
int CpuSuspendIntr(int *state)
Definition intrman.c:205
Definition alarm.c:28