blob: ec4b987e70916cea9a71374a80251552d2614ae4 [file] [log] [blame]
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -07001/*
Travis Geiselbrecht671cb792009-06-28 11:27:48 -07002 * Copyright (c) 2008-2009 Travis Geiselbrecht
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -07003 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
Travis Geiselbrecht12403e32010-05-06 13:36:57 -070024/**
25 * @defgroup debug Debug
26 * @{
27 */
28
29/**
30 * @file
31 * @brief Debug console functions.
32 */
33
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -070034#include <debug.h>
35#include <kernel/thread.h>
36#include <kernel/timer.h>
37#include <platform.h>
38
Travis Geiselbrecht671cb792009-06-28 11:27:48 -070039#if WITH_LIB_CONSOLE
Travis Geiselbrecht39deded2009-01-24 20:12:27 -080040#include <lib/console.h>
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -070041
42static int cmd_threads(int argc, const cmd_args *argv);
43static int cmd_threadstats(int argc, const cmd_args *argv);
44static int cmd_threadload(int argc, const cmd_args *argv);
45
46STATIC_COMMAND_START
47#if DEBUGLEVEL > 1
Travis Geiselbrecht671cb792009-06-28 11:27:48 -070048STATIC_COMMAND("threads", "list kernel threads", &cmd_threads)
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -070049#endif
50#if THREAD_STATS
Travis Geiselbrecht671cb792009-06-28 11:27:48 -070051STATIC_COMMAND("threadstats", "thread level statistics", &cmd_threadstats)
52STATIC_COMMAND("threadload", "toggle thread load display", &cmd_threadload)
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -070053#endif
54STATIC_COMMAND_END(kernel);
55
56#if DEBUGLEVEL > 1
57static int cmd_threads(int argc, const cmd_args *argv)
58{
59 printf("thread list:\n");
60 dump_all_threads();
61
62 return 0;
63}
64#endif
65
66#if THREAD_STATS
67static int cmd_threadstats(int argc, const cmd_args *argv)
68{
69 printf("thread stats:\n");
70 printf("\ttotal idle time: %lld\n", thread_stats.idle_time);
71 printf("\ttotal busy time: %lld\n", current_time_hires() - thread_stats.idle_time);
72 printf("\treschedules: %d\n", thread_stats.reschedules);
73 printf("\tcontext_switches: %d\n", thread_stats.context_switches);
74 printf("\tpreempts: %d\n", thread_stats.preempts);
75 printf("\tyields: %d\n", thread_stats.yields);
76 printf("\tinterrupts: %d\n", thread_stats.interrupts);
77 printf("\ttimer interrupts: %d\n", thread_stats.timer_ints);
78 printf("\ttimers: %d\n", thread_stats.timers);
79
80 return 0;
81}
82
83static enum handler_return threadload(struct timer *t, time_t now, void *arg)
84{
85 static struct thread_stats old_stats;
86 static bigtime_t last_idle_time;
87
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -070088 bigtime_t idle_time = thread_stats.idle_time;
89 if (current_thread == idle_thread) {
90 idle_time += current_time_hires() - thread_stats.last_idle_timestamp;
91 }
92 bigtime_t busy_time = 1000000ULL - (idle_time - last_idle_time);
93
94 uint busypercent = (busy_time * 10000) / (1000000);
95
96// printf("idle_time %lld, busytime %lld\n", idle_time - last_idle_time, busy_time);
97 printf("LOAD: %d.%02d%%, cs %d, ints %d, timer ints %d, timers %d\n", busypercent / 100, busypercent % 100,
98 thread_stats.context_switches - old_stats.context_switches,
99 thread_stats.interrupts - old_stats.interrupts,
100 thread_stats.timer_ints - old_stats.timer_ints,
101 thread_stats.timers - old_stats.timers);
102
103 old_stats = thread_stats;
104 last_idle_time = idle_time;
105
106 return INT_NO_RESCHEDULE;
107}
108
109static int cmd_threadload(int argc, const cmd_args *argv)
110{
111 static bool showthreadload = false;
112 static timer_t tltimer;
113
114 enter_critical_section();
115
116 if (showthreadload == false) {
117 // start the display
118 timer_initialize(&tltimer);
Travis Geiselbrecht671cb792009-06-28 11:27:48 -0700119 timer_set_periodic(&tltimer, 1000, &threadload, NULL);
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700120 showthreadload = true;
121 } else {
122 timer_cancel(&tltimer);
123 showthreadload = false;
124 }
125
126 exit_critical_section();
127
128 return 0;
129}
130
131#endif
132
133#endif
134