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 *), u32 priority, u32 stacksize, u32 option);
47static int do_get_thread_count();
48static void ThmonMonitorThread(struct thmon_thcpuwatch_param *usrptr);
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, (void (*)(void *))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 *), 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(struct thmon_thcpuwatch_param *usrptr)
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
578 chrcnt = 0;
579 delayval = 1000 * (1000 / usrptr->m_sample_count);
580 usrptr->m_start_stop_status = 1;
581 target_thread = usrptr->m_thread;
582 this_thread = (struct thread *)HANDLE_PTR(GetThreadId());
583 this_thread_clks_2.lo = 0;
584 this_thread_clks_2.hi = 0;
585 while (usrptr->m_start_stop_status != 2) {
586 if (target_thread) {
587 target_thread_clks_1.hi = target_thread->run_clocks_hi;
588 target_thread_clks_1.lo = target_thread->run_clocks_lo;
589 DelayThread(delayval);
590 GetSystemTime(&sys_time_clks_1);
591 sys_clock_subtract(
592 &sys_time_clks_1,
593 &sys_time_clks_2,
594 &tmp_time_clks_1);
595 sys_time_clks_2 = sys_time_clks_1;
596 target_thread_clks_2.hi = target_thread->run_clocks_hi;
597 target_thread_clks_2.lo = target_thread->run_clocks_lo;
598 this_thread_clks_1.hi = this_thread->run_clocks_hi;
599 this_thread_clks_1.lo = this_thread->run_clocks_lo;
600 sys_clock_subtract(
601 &this_thread_clks_1,
602 &this_thread_clks_2,
603 &this_thread_clks_2);
604 sys_clock_subtract(
605 &tmp_time_clks_1,
606 &this_thread_clks_2,
607 &tmp_time_clks_1);
608 this_thread_clks_2 = this_thread_clks_1;
609 sys_clock_subtract(
610 &target_thread_clks_2,
611 &target_thread_clks_1,
612 &tmp_time_clks_2);
613 // Unofficial: use SysClock2USec
614 // TODO: giant magic math function tmp_time_clks_1, tmp_time_clks_2
615 SysClock2USec(&tmp_time_clks_1, &sec, &usec);
616 switch (usrptr->m_barchart) {
617 case 0:
618 Kprintf("%3d.%03d %07x", sec, usec, target_thread->saved_regs->pc);
619 if (usrptr->m_verbose) {
620 Kprintf(
621 " %6d/%6d/%6d ",
622 target_thread->irq_preemption_count,
623 target_thread->thread_preemption_count,
624 target_thread->release_count);
625 Kprintf("%c", (chrcnt <= 0) ? ' ' : '\n');
626 ++chrcnt;
627 if (chrcnt >= 2)
628 chrcnt = 0;
629 } else {
630 Kprintf("%c", (chrcnt < 4) ? ' ' : '\n');
631 ++chrcnt;
632 if (chrcnt >= 5)
633 chrcnt = 0;
634 }
635 break;
636 case 1:
637 case 2:
638 Kprintf(
639 "%3d.%03d:%s",
640 sec,
641 usec,
642 (usrptr->m_barchart == 1) ? do_output_progress_bar_newline(sec * 1000 + usec) : do_output_progress_bar_carriageret(sec * 1000 + usec));
643 break;
644 default:
645 break;
646 }
647 } else {
648 target_thread_clks_1.hi = g_ThbaseInternal->idle_thread->run_clocks_hi;
649 target_thread_clks_1.lo = g_ThbaseInternal->idle_thread->run_clocks_lo;
650 GetSystemTime(&sys_time_clks_2);
651 DelayThread(delayval);
652 GetSystemTime(&sys_time_clks_1);
653 target_thread_clks_2.hi = g_ThbaseInternal->idle_thread->run_clocks_hi;
654 target_thread_clks_2.lo = g_ThbaseInternal->idle_thread->run_clocks_lo;
655 sys_clock_subtract(
656 &sys_time_clks_1,
657 &sys_time_clks_2,
658 &tmp_time_clks_1);
659 sys_clock_subtract(
660 &target_thread_clks_2,
661 &target_thread_clks_1,
662 &tmp_time_clks_2);
663 // Unofficial: use SysClock2USec
664 // TODO: giant magic math function tmp_time_clks_1, tmp_time_clks_2
665 SysClock2USec(&tmp_time_clks_1, &sec, &usec);
666 math_magic_3 = 100000 - (sec * 1000 + usec);
667 switch (usrptr->m_barchart) {
668 case 0:
669 Kprintf("%3d.%03d", math_magic_3 / 1000, math_magic_3 % 1000);
670 if (usrptr->m_verbose) {
671 Kprintf(
672 " %6d/%6d%s",
673 g_ThbaseInternal->thread_switch_count,
674 g_ThbaseInternal->idle_thread->irq_preemption_count,
675 (chrcnt < 2) ? " " : "\n");
676 ++chrcnt;
677 if (chrcnt >= 3)
678 chrcnt = 0;
679 } else {
680 Kprintf((chrcnt < 8) ? " " : "\n");
681 ++chrcnt;
682 if (chrcnt >= 9)
683 chrcnt = 0;
684 }
685 break;
686 case 1:
687 case 2:
688 Kprintf(
689 "%3d.%03d:%s",
690 math_magic_3 / 1000,
691 math_magic_3 % 1000,
692 (usrptr->m_barchart == 1) ? do_output_progress_bar_newline(math_magic_3) : do_output_progress_bar_carriageret(math_magic_3));
693 break;
694 default:
695 break;
696 }
697 }
698 }
699 usrptr->m_start_stop_status = 0;
700}
701
702static void do_stop_current_thcpuwatch()
703{
704 if (!g_thcpuwatch_info.m_start_stop_status) {
705 return;
706 }
707 g_thcpuwatch_info.m_start_stop_status = 2;
708 while (g_thcpuwatch_info.m_start_stop_status) {
709 DelayThread(1000);
710 }
711}
712
713static void thwatch_cmd_handler(char *cmdparam)
714{
715 char *cmdparam_cur;
716 int is_flag_b_or_br;
717 int integer_value;
718 int hex_value;
719 int is_flag_v;
720 char *EndOfString;
721
722 iop_thread_info_t thstatus;
723
724 is_flag_b_or_br = 0;
725 integer_value = 10;
726 hex_value = 0;
727 is_flag_v = 0;
728 for (cmdparam_cur = cmdparam; *cmdparam_cur; cmdparam_cur = EndOfString) {
729 EndOfString = GetEndOfString(cmdparam_cur);
730 if (*EndOfString) {
731 *EndOfString = 0;
732 EndOfString = RemoveLeadingWhitespaces(EndOfString + 1);
733 }
734 if (!strcmp(cmdparam_cur, "-b"))
735 is_flag_b_or_br = 1;
736 if (!strcmp(cmdparam_cur, "-br"))
737 is_flag_b_or_br = 2;
738 if (!strcmp(cmdparam_cur, "-v"))
739 is_flag_v = 1;
740 if (*cmdparam_cur != '-') {
741 if (hex_value)
742 integer_value = strtol(cmdparam_cur, 0, 10);
743 else
744 hex_value = do_parse_hex(cmdparam_cur);
745 }
746 }
747 do_stop_current_thcpuwatch();
748 if (!hex_value) {
749 return;
750 }
751 if (hex_value < g_ThbaseInternal->thread_id) {
752 struct thread *thread;
753
754 list_for_each (thread, &g_ThbaseInternal->thread_list, thread_list) {
755 if (thread->tag.id == hex_value)
756 break;
757 }
758 if (!thread || thread->tag.id != hex_value) {
759 fdprintf(g_tty9_fd, "thread #%d not found \n", hex_value);
760 return;
761 }
762 hex_value = MAKE_HANDLE(thread);
763 }
764 g_thcpuwatch_info.m_barchart = is_flag_b_or_br;
765 g_thcpuwatch_info.m_sample_count = integer_value;
766 g_thcpuwatch_info.m_verbose = is_flag_v;
767 if (hex_value <= 0 || ReferThreadStatus(hex_value, &thstatus)) {
768 fdprintf(g_tty9_fd, "thid:%x not found \n", hex_value);
769 } else if (integer_value > 0) {
770 g_thcpuwatch_info.m_thread = (struct thread *)HANDLE_PTR(hex_value);
771 fdprintf(g_tty9_fd, "Thread %x time watching and print to ITTYK\n", hex_value);
772 StartThread(g_monitorThreadId, &g_thcpuwatch_info);
773 }
774}
775
776static void cpuwatch_cmd_handler(char *cmdparam)
777{
778 char *cmdparam_cur;
779 int is_flag_b_or_br;
780 int int_value;
781 int is_flag_v;
782 char *EndOfString;
783
784 is_flag_b_or_br = 0;
785 int_value = 10;
786 is_flag_v = 0;
787 for (cmdparam_cur = cmdparam; *cmdparam_cur; cmdparam_cur = EndOfString) {
788 EndOfString = GetEndOfString(cmdparam_cur);
789 if (*EndOfString) {
790 *EndOfString = 0;
791 EndOfString = RemoveLeadingWhitespaces(EndOfString + 1);
792 }
793 if (!strcmp(cmdparam_cur, "-b"))
794 is_flag_b_or_br = 1;
795 if (!strcmp(cmdparam_cur, "-br"))
796 is_flag_b_or_br = 2;
797 if (!strcmp(cmdparam_cur, "-v"))
798 is_flag_v = 1;
799 if (*cmdparam_cur != '-')
800 int_value = strtol(cmdparam_cur, 0, 10);
801 }
802 do_stop_current_thcpuwatch();
803 if (int_value > 0) {
804 g_thcpuwatch_info.m_barchart = is_flag_b_or_br;
805 g_thcpuwatch_info.m_sample_count = int_value;
806 g_thcpuwatch_info.m_verbose = is_flag_v;
807 g_thcpuwatch_info.m_thread = 0;
808 fdprintf(g_tty9_fd, "CPU time watching and print to ITTYK\n");
809 StartThread(g_monitorThreadId, &g_thcpuwatch_info);
810 }
811}
812
813static void rdlist_cmd_handler(char *cmdparam)
814{
815 char *cmdparam_cur;
816 int is_flag_v;
817 int is_flag_i;
818 char *EndOfString;
819 int i;
820 struct thread *thread;
821 iop_thread_info_t thstatus;
822
823 is_flag_v = 0;
824 is_flag_i = 0;
825 for (cmdparam_cur = cmdparam; *cmdparam_cur; cmdparam_cur = EndOfString) {
826 EndOfString = GetEndOfString(cmdparam_cur);
827 if (*EndOfString) {
828 *EndOfString = 0;
829 EndOfString = RemoveLeadingWhitespaces(EndOfString + 1);
830 }
831 if (!strcmp(cmdparam_cur, "-v"))
832 is_flag_v = 1;
833 if (!strcmp(cmdparam_cur, "-i"))
834 is_flag_i = 1;
835 }
836 fdprintf(g_tty9_fd, " THID ATTR OPTION STS ENTRY STACK SSIZE GP CP IP WT WID WUC\n");
837 for (i = 1; i < (is_flag_i + 127); i += 1) {
838 if (list_empty(&g_ThbaseInternal->ready_queue[i])) {
839 continue;
840 }
841 list_for_each (thread, &g_ThbaseInternal->ready_queue[i], queue) {
842 if (!ReferThreadStatus(MAKE_HANDLE(thread), &thstatus))
843 DisplayThreadInformation(thread, is_flag_v, 0);
844 }
845 }
846}
847
848static void sllist_cmd_handler(char *cmdparam)
849{
850 char *cmdparam_cur;
851 int is_flag_v;
852 char *EndOfString;
853 struct thread *thread;
854 iop_thread_info_t thstatus;
855
856 is_flag_v = 0;
857 for (cmdparam_cur = cmdparam; *cmdparam_cur; cmdparam_cur = EndOfString) {
858 EndOfString = GetEndOfString(cmdparam_cur);
859 if (*EndOfString) {
860 *EndOfString = 0;
861 EndOfString = RemoveLeadingWhitespaces(EndOfString + 1);
862 }
863 if (!strcmp(cmdparam_cur, "-v"))
864 is_flag_v = 1;
865 }
866 fdprintf(g_tty9_fd, " THID ATTR OPTION STS ENTRY STACK SSIZE GP CP IP WT WID WUC\n");
867 list_for_each (thread, &g_ThbaseInternal->sleep_queue, queue) {
868 if (ReferThreadStatus(MAKE_HANDLE(thread), &thstatus) < 0) {
869 fdprintf(g_tty9_fd, "thid = %x not found \n", MAKE_HANDLE(thread));
870 continue;
871 }
872 if (thread != g_ThbaseInternal->idle_thread)
873 DisplayThreadInformation(thread, is_flag_v, 0);
874 }
875}
876
877static void dlist_print_thread_info(struct thread *threadstruct, int is_verbose)
878{
879 fdprintf(
880 g_tty9_fd,
881 "%3x %07x %08x %07x %.3s ",
882 threadstruct->tag.id,
883 MAKE_HANDLE(threadstruct),
884 threadstruct->attr,
885 threadstruct->option,
886 &g_th_status_short[3 * (char)threadstruct->status]);
887 fdprintf(
888 g_tty9_fd,
889 "%06x %06x %04x %06x %3d %3d %d\n",
890 threadstruct->entry,
891 threadstruct->stack_top,
892 threadstruct->stack_size,
893 threadstruct->gp,
894 (s16)threadstruct->priority,
895 (s16)threadstruct->init_priority,
896 threadstruct->wait_usecs);
897 if (is_verbose) {
898 char *module_name_from_addr;
899
900 module_name_from_addr = get_module_name_from_addr((unsigned int)threadstruct->entry);
901 if (module_name_from_addr)
902 fdprintf(g_tty9_fd, " Name=%s\n", module_name_from_addr);
903 }
904 if (threadstruct->saved_regs && threadstruct->status != 16)
905 fdprintf(
906 g_tty9_fd,
907 " PC=%06x RA=%06x SP=%06x Context_addr/mask=%08x/%08x\n",
908 threadstruct->saved_regs->pc,
909 threadstruct->saved_regs->ra,
910 threadstruct->saved_regs->sp,
911 threadstruct->saved_regs,
912 threadstruct->saved_regs->unk);
913 if (is_verbose) {
914 unsigned int i;
915
916 for (i = 0; i < (threadstruct->stack_size / 4); i += 1) {
917 if (((u32 *)threadstruct->stack_top)[i] != 0xFFFFFFFF && ((u32 *)threadstruct->stack_top)[i] != 0x11111111)
918 break;
919 }
920 fdprintf(g_tty9_fd, " Free_Stack_Size=%06x\n", i * 4);
921 }
922}
923
924static void dllist_cmd_handler(char *cmdparam)
925{
926 char *cmdparam_cur;
927 int is_flag_v;
928 char *EndOfString;
929 struct thread *thread;
930 iop_thread_info_t thstatus;
931
932 is_flag_v = 0;
933 for (cmdparam_cur = cmdparam; *cmdparam_cur; cmdparam_cur = EndOfString) {
934 EndOfString = GetEndOfString(cmdparam_cur);
935 if (*EndOfString) {
936 *EndOfString = 0;
937 EndOfString = RemoveLeadingWhitespaces(EndOfString + 1);
938 }
939 if (!strcmp(cmdparam_cur, "-v"))
940 is_flag_v = 1;
941 }
942 fdprintf(g_tty9_fd, " THID ATTR OPTION STS ENTRY STACK SSIZE GP CP IP USEC\n");
943 list_for_each (thread, &g_ThbaseInternal->delay_queue, queue) {
944 if (ReferThreadStatus(MAKE_HANDLE(thread), &thstatus) < 0) {
945 fdprintf(g_tty9_fd, "thid = %x not found \n", MAKE_HANDLE(thread));
946 continue;
947 }
948 if (thread != g_ThbaseInternal->idle_thread)
949 dlist_print_thread_info(thread, is_flag_v);
950 }
951}
952
953static void ShowSemList(char *cmdparam)
954{
955 char *cmdparam_cur;
956 int is_flag_v_count;
957 int is_flag_w_count;
958 char *EndOfString;
959 struct semaphore *sema;
960 struct thread *waiter;
961 iop_sema_info_t semastatus;
962 iop_thread_info_t thstatus;
963
964 is_flag_v_count = 0;
965 is_flag_w_count = 0;
966 for (cmdparam_cur = cmdparam; *cmdparam_cur; cmdparam_cur = EndOfString) {
967 EndOfString = GetEndOfString(cmdparam_cur);
968 if (*EndOfString) {
969 *EndOfString = 0;
970 EndOfString = RemoveLeadingWhitespaces(EndOfString + 1);
971 }
972 if (!strcmp(cmdparam_cur, "-v"))
973 ++is_flag_v_count;
974 if (!strcmp(cmdparam_cur, "-w"))
975 ++is_flag_w_count;
976 }
977 if (list_empty(&g_ThbaseInternal->semaphore)) {
978 return;
979 }
980 fdprintf(g_tty9_fd, " SEMID ATTR OPTION iCnt cCnt mCnt waitThreads\n");
981 list_for_each (sema, &g_ThbaseInternal->semaphore, sema_list) {
982 if (ReferSemaStatus(MAKE_HANDLE(sema), &semastatus) < 0) {
983 continue;
984 }
985 if (semastatus.numWaitThreads > 0 || !is_flag_w_count) {
986 fdprintf(
987 g_tty9_fd,
988 "%3x %07x %08x %08x %05d %5d %5d %5d\n",
989 sema->tag.id,
990 MAKE_HANDLE(sema),
991 semastatus.attr,
992 semastatus.option,
993 semastatus.initial,
994 semastatus.current,
995 semastatus.max,
996 semastatus.numWaitThreads);
997 }
998 if (semastatus.numWaitThreads > 0 && is_flag_w_count) {
999 fdprintf(g_tty9_fd, " THID ATTR OPTION STS ENTRY STACK SSIZE GP CP IP\n");
1000 list_for_each_safe (waiter, &sema->event.waiters, queue) {
1001 ReferThreadStatus(MAKE_HANDLE(waiter), &thstatus);
1002 DisplayThreadInformation(waiter, is_flag_v_count, 1);
1003 }
1004 }
1005 }
1006}
1007
1008static void ShowEventFlagList(char *cmdparam)
1009{
1010 char *cmdparam_cur;
1011 int is_flag_v_count;
1012 int is_flag_w_count;
1013 char *EndOfString;
1014 struct event_flag *evf;
1015 struct thread *waiter;
1016 iop_event_info_t efstatus;
1017 iop_thread_info_t thstatus;
1018
1019 is_flag_v_count = 0;
1020 is_flag_w_count = 0;
1021 for (cmdparam_cur = cmdparam; *cmdparam_cur; cmdparam_cur = EndOfString) {
1022 EndOfString = GetEndOfString(cmdparam_cur);
1023 if (*EndOfString) {
1024 *EndOfString = 0;
1025 EndOfString = RemoveLeadingWhitespaces(EndOfString + 1);
1026 }
1027 if (!strcmp(cmdparam_cur, "-v"))
1028 ++is_flag_v_count;
1029 if (!strcmp(cmdparam_cur, "-w"))
1030 ++is_flag_w_count;
1031 }
1032 if (list_empty(&g_ThbaseInternal->event_flag)) {
1033 return;
1034 }
1035 fdprintf(g_tty9_fd, " EVID ATTR OPTION iPattern cPattern waitThreads\n");
1036 list_for_each (evf, &g_ThbaseInternal->event_flag, evf_list) {
1037 if (ReferEventFlagStatus(MAKE_HANDLE(evf), &efstatus) < 0) {
1038 continue;
1039 }
1040 if (efstatus.numThreads > 0 || !is_flag_w_count) {
1041 fdprintf(
1042 g_tty9_fd,
1043 "%3x %07x %08x %08x %08x %08x %5d\n",
1044 evf->tag.id,
1045 MAKE_HANDLE(evf),
1046 efstatus.attr,
1047 efstatus.option,
1048 efstatus.initBits,
1049 efstatus.currBits,
1050 efstatus.numThreads);
1051 }
1052 if (efstatus.numThreads > 0 && is_flag_w_count) {
1053 fdprintf(g_tty9_fd, " THID ATTR OPTION STS ENTRY STACK SSIZE GP CP IP\n");
1054 list_for_each_safe (waiter, &evf->event.waiters, queue) {
1055 ReferThreadStatus(MAKE_HANDLE(waiter), &thstatus);
1056 DisplayThreadInformation(waiter, is_flag_v_count, 1);
1057 }
1058 }
1059 }
1060}
1061
1062static void ShowMsgbxList()
1063{
1064 struct mbox *mbx;
1065 iop_mbx_status_t mbxstatus;
1066
1067 if (list_empty(&g_ThbaseInternal->mbox)) {
1068 return;
1069 }
1070 fdprintf(g_tty9_fd, " MSGID ATTR OPTION waitThreads messages\n");
1071 list_for_each (mbx, &g_ThbaseInternal->mbox, mbox_list) {
1072 ReferMbxStatus(MAKE_HANDLE(mbx), &mbxstatus);
1073 fdprintf(
1074 g_tty9_fd,
1075 "%3x %07x %08x %08x %5d %5d\n",
1076 mbx->tag.id,
1077 MAKE_HANDLE(mbx),
1078 mbxstatus.attr,
1079 mbxstatus.option,
1080 mbxstatus.numWaitThreads,
1081 mbxstatus.numMessage);
1082 }
1083}
1084
1085static void ShowVplList()
1086{
1087 struct vpool *vpl;
1088 iop_vpl_info_t vplstatus;
1089
1090 if (list_empty(&g_ThbaseInternal->vpool)) {
1091 return;
1092 }
1093 fdprintf(g_tty9_fd, " VPLID ATTR OPTION Size Free waitThreads\n");
1094 list_for_each (vpl, &g_ThbaseInternal->vpool, vpl_list) {
1095 ReferVplStatus(MAKE_HANDLE(vpl), &vplstatus);
1096 fdprintf(
1097 g_tty9_fd,
1098 "%3x %07x %08x %08x %06x %06x %5d\n",
1099 vpl->tag.id,
1100 MAKE_HANDLE(vpl),
1101 vplstatus.attr,
1102 vplstatus.option,
1103 vplstatus.size,
1104 vplstatus.freeSize,
1105 vplstatus.numWaitThreads);
1106 }
1107}
1108
1109static void ShowFplList()
1110{
1111 struct fpool *fpl;
1112 iop_fpl_info_t fplstatus;
1113
1114 if (list_empty(&g_ThbaseInternal->fpool)) {
1115 return;
1116 }
1117 fdprintf(g_tty9_fd, " FPLID ATTR OPTION BlkSIze AllBlocks FreeSize waitThreads\n");
1118 list_for_each (fpl, &g_ThbaseInternal->fpool, fpl_list) {
1119 ReferFplStatus(MAKE_HANDLE(fpl), &fplstatus);
1120 fdprintf(
1121 g_tty9_fd,
1122 "%3x %07x %08x %08x %06x %06x %06x %5d\n",
1123 fpl->tag.id,
1124 MAKE_HANDLE(fpl),
1125 fplstatus.attr,
1126 fplstatus.option,
1127 fplstatus.blockSize,
1128 fplstatus.numBlocks,
1129 fplstatus.freeBlocks,
1130 fplstatus.numWaitThreads);
1131 }
1132}
1133
1134static void DumpReadyQueue()
1135{
1136 struct thread *thread;
1137 int i;
1138 int state;
1139
1140 fdprintf(g_tty9_fd, "ready queue ----\n");
1141 for (i = 0; i < 127; i += 1) {
1142 if (list_empty(&g_ThbaseInternal->ready_queue[i])) {
1143 continue;
1144 }
1145 CpuSuspendIntr(&state);
1146 fdprintf(g_tty9_fd, " %3d:%x ", i, &g_ThbaseInternal->ready_queue[i]);
1147 list_for_each (thread, &g_ThbaseInternal->ready_queue[i], queue)
1148 fdprintf(g_tty9_fd, " %d(%x) ", thread->tag.id, thread);
1149 fdprintf(g_tty9_fd, "\n");
1150 CpuResumeIntr(state);
1151 }
1152 fdprintf(g_tty9_fd, "ready map = ");
1153 for (i = 0; i < 4; i += 1) {
1154 fdprintf(g_tty9_fd, "%08x ", g_ThbaseInternal->queue_map[i]);
1155 }
1156 fdprintf(g_tty9_fd, "\n");
1157}
1158
1159static void ToggleThswdisp(const char *cmdparam)
1160{
1161 if (!strcmp(cmdparam, "on"))
1162 g_ThbaseInternal->debug_flags |= 1u;
1163 if (!strcmp(cmdparam, "off"))
1164 g_ThbaseInternal->debug_flags &= ~1u;
1165 if (isdigit(*cmdparam))
1166 g_ThbaseInternal->debug_flags = strtol(cmdparam, 0, 10);
1167}
1168
1169static void ToggleThLED(const char *cmdparam)
1170{
1171 if (!strcmp(cmdparam, "on"))
1172 g_ThbaseInternal->debug_flags |= 0x20u;
1173 if (!strcmp(cmdparam, "off"))
1174 g_ThbaseInternal->debug_flags &= ~0x20u;
1175 if (isdigit(*cmdparam))
1176 g_ThbaseInternal->debug_flags = strtol(cmdparam, 0, 10);
1177}
1178
1179static void ToggleWarnDisp(const char *cmdparam)
1180{
1181 if (!strcmp(cmdparam, "on"))
1182 g_ThbaseInternal->debug_flags |= 8u;
1183 if (!strcmp(cmdparam, "off"))
1184 g_ThbaseInternal->debug_flags &= ~8u;
1185 if (isdigit(*cmdparam))
1186 g_ThbaseInternal->debug_flags = strtol(cmdparam, 0, 10);
1187}
1188
1189static void DumpThreads()
1190{
1191 struct thread *thread;
1192
1193 fdprintf(g_tty9_fd, "===============================\n");
1194 fdprintf(g_tty9_fd, "tcb list ----\n");
1195 list_for_each (thread, &g_ThbaseInternal->thread_list, thread_list) {
1196 fdprintf(
1197 g_tty9_fd,
1198 " %d: tcb=%x sts=0x%x pri=%d ",
1199 thread->tag.id,
1200 thread,
1201 (char)thread->status,
1202 (s16)thread->priority);
1203 if ((char)thread->status == 4)
1204 fdprintf(g_tty9_fd, "wType = %x:%x ", (s16)thread->wait_type, thread->wait_usecs);
1205 if ((char)thread->status != 1)
1206 fdprintf(g_tty9_fd, "contx=%x sp=%x", thread->saved_regs, thread->saved_regs->sp);
1207 fdprintf(g_tty9_fd, "\n");
1208 }
1209 fdprintf(g_tty9_fd, "sleep list ----\n");
1210 if (list_empty(&g_ThbaseInternal->sleep_queue)) {
1211 return;
1212 }
1213 fdprintf(g_tty9_fd, " %x: ", &g_ThbaseInternal->sleep_queue);
1214 list_for_each (thread, &g_ThbaseInternal->sleep_queue, queue) {
1215 fdprintf(g_tty9_fd, " %d(%x) ", thread->tag.id, thread);
1216 }
1217 fdprintf(g_tty9_fd, "\n");
1218}
1219
1220static void ShowAlarmList()
1221{
1222 struct thmon_almlist_item *alarm_ents;
1223 int alarm_cnt;
1224 struct alarm *alarm;
1225 int i;
1226 int state;
1227
1228 alarm_ents = 0;
1229 CpuSuspendIntr(&state);
1230 alarm_cnt = 0;
1231 if (!list_empty(&g_ThbaseInternal->alarm)) {
1232 list_for_each (alarm, &g_ThbaseInternal->alarm, alarm_list) {
1233 alarm_cnt += 1;
1234 }
1235 alarm_ents = __builtin_alloca(alarm_cnt * sizeof(struct thmon_almlist_item));
1236 i = 0;
1237 list_for_each (alarm, &g_ThbaseInternal->alarm, alarm_list) {
1238 alarm_ents[i].m_alarm_id = alarm->tag.id;
1239 alarm_ents[i].m_target.lo = alarm->target;
1240 alarm_ents[i].m_target.hi = alarm->target >> 32;
1241 alarm_ents[i].m_cb = alarm->cb;
1242 alarm_ents[i].m_userptr = alarm->userptr;
1243 i += 1;
1244 }
1245 }
1246 CpuResumeIntr(state);
1247 fdprintf(g_tty9_fd, " NUM TIME HANDLER COMMON\n");
1248 for (i = 0; i < alarm_cnt; i += 1) {
1249 fdprintf(
1250 g_tty9_fd,
1251 "%3x %08x_%08x %06x, %08x\n",
1252 alarm_ents[i].m_alarm_id,
1253 alarm_ents[i].m_target.hi,
1254 alarm_ents[i].m_target.lo,
1255 alarm_ents[i].m_cb,
1256 alarm_ents[i].m_userptr);
1257 }
1258}
1259
1260static void freemem_cmd_handler()
1261{
1262 u32 TotalFreeMemSize;
1263
1264 TotalFreeMemSize = QueryTotalFreeMemSize();
1265 fdprintf(
1266 g_tty9_fd,
1267 "IOP system memory 0x%x(%d) byte free, Max free block size 0x%x\n",
1268 TotalFreeMemSize,
1269 TotalFreeMemSize,
1270 QueryMaxFreeMemSize());
1271}
1272
1273static void ThmonMainThread(void *arg)
1274{
1275 char *cmdbufsrc;
1276 char *cmdbufdst;
1277 char *cmdbuf_trim;
1278 char *cmdparam;
1279
1280 (void)arg;
1281
1282 fdprintf(g_tty9_fd, "\n\n========= simple thread monitor program =========\n");
1283 fdprintf(g_tty9_fd, "help command is 'help'\n");
1284 g_PreviousCommand[0] = 0;
1285 for (;;) {
1286 fdprintf(g_tty9_fd, " > ");
1287 if (!fdgets(g_CommandBuffer, g_tty9_fd))
1288 break;
1289 PrintMessage(g_CommandBuffer);
1290 if (!strlen(g_CommandBuffer))
1291 continue;
1292 if (!strcmp(g_CommandBuffer, "/")) {
1293 cmdbufsrc = g_PreviousCommand;
1294 cmdbufdst = g_CommandBuffer;
1295 } else {
1296 cmdbufsrc = g_CommandBuffer;
1297 cmdbufdst = g_PreviousCommand;
1298 }
1299 strcpy(cmdbufdst, cmdbufsrc);
1300 cmdbuf_trim = RemoveLeadingWhitespaces(g_CommandBuffer);
1301 cmdparam = RemoveLeadingWhitespaces(GetEndOfString(cmdbuf_trim));
1302 if (*cmdbuf_trim == '#')
1303 continue;
1304 if (!strncmp("quit", cmdbuf_trim, strlen(cmdbuf_trim)))
1305 break;
1306 else if (!strncmp("?", cmdbuf_trim, strlen(cmdbuf_trim)) || !strncmp("help", cmdbuf_trim, strlen(cmdbuf_trim)))
1307 DisplayHelpMessage();
1308 else if (!strncmp("thlist", cmdbuf_trim, strlen(cmdbuf_trim)))
1309 thlist_cmd_handler(cmdparam);
1310 else if (!strncmp("rdlist", cmdbuf_trim, strlen(cmdbuf_trim)))
1311 rdlist_cmd_handler(cmdparam);
1312 else if (!strncmp("sllist", cmdbuf_trim, strlen(cmdbuf_trim)))
1313 sllist_cmd_handler(cmdparam);
1314 else if (!strncmp("dllist", cmdbuf_trim, strlen(cmdbuf_trim)))
1315 dllist_cmd_handler(cmdparam);
1316 else if (!strncmp("rtlist", cmdbuf_trim, strlen(cmdbuf_trim)))
1317 rtlist_cmd_handler(cmdparam);
1318 else if (!strncmp("semlist", cmdbuf_trim, strlen(cmdbuf_trim)))
1319 ShowSemList(cmdparam);
1320 else if (!strncmp("evlist", cmdbuf_trim, strlen(cmdbuf_trim)))
1321 ShowEventFlagList(cmdparam);
1322 else if (!strncmp("msglist", cmdbuf_trim, strlen(cmdbuf_trim)))
1323 ShowMsgbxList();
1324 else if (!strncmp("vpllist", cmdbuf_trim, strlen(cmdbuf_trim)))
1325 ShowVplList();
1326 else if (!strncmp("fpllist", cmdbuf_trim, strlen(cmdbuf_trim)))
1327 ShowFplList();
1328 else if (!strncmp("almlist", cmdbuf_trim, strlen(cmdbuf_trim)))
1329 ShowAlarmList();
1330 else if (!strncmp("freemem", cmdbuf_trim, strlen(cmdbuf_trim)))
1331 freemem_cmd_handler();
1332 else if (!strncmp("cpuwatch", cmdbuf_trim, strlen(cmdbuf_trim)))
1333 cpuwatch_cmd_handler(cmdparam);
1334 else if (!strncmp("thwatch", cmdbuf_trim, strlen(cmdbuf_trim)))
1335 thwatch_cmd_handler(cmdparam);
1336 else if (!strncmp("thswdisp", cmdbuf_trim, strlen(cmdbuf_trim)))
1337 ToggleThswdisp(cmdparam);
1338 else if (!strncmp("thled", cmdbuf_trim, strlen(cmdbuf_trim)))
1339 ToggleThLED(cmdparam);
1340 else if (!strncmp("warndisp", cmdbuf_trim, strlen(cmdbuf_trim)))
1341 ToggleWarnDisp(cmdparam);
1342 else if (!strncmp("dumpthread", cmdbuf_trim, strlen(cmdbuf_trim)))
1343 DumpThreads();
1344 else if (!strncmp("dumpready", cmdbuf_trim, strlen(cmdbuf_trim)))
1345 DumpReadyQueue();
1346 else
1347 fdprintf(g_tty9_fd, " ?? \n");
1348 }
1349}
int CpuResumeIntr(int state)
Definition intrman.c:227
int CpuSuspendIntr(int *state)
Definition intrman.c:205
Definition alarm.c:28