optimize the menuconfig redrawing
[lunaix-os.git] / lunaix-os / includes / lunaix / kpreempt.h
1 #ifndef __LUNAIX_KPREEMPT_H
2 #define __LUNAIX_KPREEMPT_H
3
4 #include <sys/abi.h>
5 #include <sys/cpu.h>
6 #include <lunaix/process.h>
7
8 #define _preemptible \
9         __attribute__((section(".kf.preempt"))) no_inline
10
11 #define ensure_preempt_caller()                                 \
12     do {                                                        \
13         extern int __kf_preempt_start[];                        \
14         extern int __kf_preempt_end[];                          \
15         ptr_t _retaddr = abi_get_retaddr();                     \
16         assert_msg((ptr_t)__kf_preempt_start <= _retaddr        \
17                     && _retaddr < (ptr_t)__kf_preempt_end,      \
18                    "caller must be kernel preemptible");        \
19     } while(0)
20
21 static inline void
22 set_preemption() 
23 {
24     cpu_enable_interrupt();
25 }
26
27 static inline void
28 no_preemption() 
29 {
30     cpu_disable_interrupt();
31 }
32
33 static inline void
34 __schedule_away()
35 {
36     current_thread->stats.last_reentry = clock_systime();
37     
38     cpu_trap_sched();
39     set_preemption();
40 }
41
42 /**
43  * @brief preempt the current thread, and yield the remaining
44  *        time slice to other threads.
45  * 
46  *        The current thread is marked as if it is being
47  *        preempted involuntarily by kernel.
48  * 
49  */
50 static inline void
51 preempt_current()
52 {
53     no_preemption();
54     thread_stats_update_kpreempt();
55     __schedule_away();
56 }
57
58 /**
59  * @brief yield the remaining time slice to other threads.
60  * 
61  *        The current thread is marked as if it is being
62  *        preempted voluntarily by itself.
63  * 
64  */
65 static inline void
66 yield_current()
67 {
68     no_preemption();
69     __schedule_away();
70 }
71
72 bool
73 preempt_check_stalled(struct thread* th);
74
75 #endif /* __LUNAIX_KPREEMPT_H */