optimize the menuconfig redrawing
[lunaix-os.git] / lunaix-os / kernel / process / preemption.c
1 #include <lunaix/kpreempt.h>
2 #include <lunaix/process.h>
3 #include <lunaix/switch.h>
4 #include <lunaix/syslog.h>
5 #include <lunaix/trace.h>
6
7 LOG_MODULE("preempt");
8
9 #ifdef CONFIG_CHECK_STALL
10 bool
11 preempt_check_stalled(struct thread* th)
12 {
13     // we can't access the hart state here
14     //  as th might be in other address space
15
16     if (thread_flags_test(th, TH_STALLED))
17     {
18         // alrady stalled, no need to concern
19         return false;
20     }
21
22     struct thread_stats* stats;
23     stats   = &th->stats;
24
25     if (!stats->kpreempt_count) {
26         return false;
27     }
28
29     if (stats->at_user) {
30         return false;
31     }
32
33 #if defined(CONFIG_STALL_MAX_PREEMPTS) && CONFIG_STALL_MAX_PREEMPTS
34     if (stats->kpreempt_count > CONFIG_STALL_MAX_PREEMPTS) {
35         return true;
36     }
37 #endif
38
39     ticks_t total_elapsed;
40     total_elapsed = thread_stats_kernel_elapse(th);
41
42     return total_elapsed > ticks_seconds(CONFIG_STALL_TIMEOUT);
43 }
44
45 #else 
46 bool
47 preempt_check_stalled(struct thread* th)
48 {
49     return false;
50 }
51
52 #endif
53
54 void
55 preempt_handle_stalled(struct signpost_result* result)
56 {
57     if (!thread_flags_test(current_thread, TH_STALLED))
58     {
59         continue_switch(result);
60         return;
61     }
62
63     kprintf("+++++ ");
64     kprintf(" stalling detected (pid: %d, tid: %d)", 
65                 __current->pid, current_thread->tid);
66     kprintf(" (preempted: %d, elapsed: %dms)", 
67                 current_thread->stats.kpreempt_count, 
68                 thread_stats_kernel_elapse(current_thread));
69     kprintf("   are you keeping Luna too busy?");
70     kprintf("+++++ ");
71
72     kprintf("last known state:");
73     trace_dump_state(current_thread->hstate);
74
75     kprintf("trace from the point of stalling:");
76     trace_printstack_isr(current_thread->hstate);
77
78     kprintf("thread is blocked");
79
80     block_current_thread();
81     giveup_switch(result);
82 }