xref: /haiku/headers/private/kernel/kscheduler.h (revision 97901ec593ec4dd50ac115c1c35a6d72f6e489a5)
1 /*
2  * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Copyright 2005-2010, Axel Dörfler, axeld@pinc-software.de.
4  * Distributed under the terms of the MIT License.
5  */
6 #ifndef KERNEL_SCHEDULER_H
7 #define KERNEL_SCHEDULER_H
8 
9 
10 #include <cpu.h>
11 #include <int.h>
12 #include <smp.h>
13 #include <thread_types.h>
14 
15 
16 struct scheduling_analysis;
17 struct thread;
18 struct SchedulerListener;
19 
20 
21 struct scheduler_ops {
22 	void (*enqueue_in_run_queue)(struct thread* thread);
23 	void (*reschedule)(void);
24 	void (*set_thread_priority)(struct thread* thread, int32 priority);
25 	bigtime_t (*estimate_max_scheduling_latency)(struct thread* thread);
26 
27 	void (*on_thread_create)(struct thread* thread);
28 		// called when the thread structure is first created -
29 		// initialization of per-thread housekeeping data structures should
30 		// be done here
31 	void (*on_thread_init)(struct thread* thread);
32 		// called when a thread structure is initialized and made ready for
33 		// use - should be used to reset the housekeeping data structures
34 		// if needed
35 	void (*on_thread_destroy)(struct thread* thread);
36 		// called when a thread structure is freed - freeing up any allocated
37 		// mem on the scheduler's part should be done here
38 
39 	void (*start)(void);
40 };
41 
42 extern struct scheduler_ops* gScheduler;
43 
44 #define scheduler_enqueue_in_run_queue(thread)	\
45 				gScheduler->enqueue_in_run_queue(thread)
46 #define scheduler_set_thread_priority(thread, priority)	\
47 				gScheduler->set_thread_priority(thread, priority)
48 #define scheduler_reschedule()	gScheduler->reschedule()
49 #define scheduler_start()		gScheduler->start()
50 #define scheduler_on_thread_create(thread) \
51 				gScheduler->on_thread_create(thread)
52 #define scheduler_on_thread_init(thread) \
53 				gScheduler->on_thread_init(thread)
54 #define scheduler_on_thread_destroy(thread) \
55 				gScheduler->on_thread_destroy(thread)
56 
57 #ifdef __cplusplus
58 extern "C" {
59 #endif
60 
61 void scheduler_add_listener(struct SchedulerListener* listener);
62 void scheduler_remove_listener(struct SchedulerListener* listener);
63 
64 void scheduler_init(void);
65 void scheduler_enable_scheduling(void);
66 
67 bigtime_t _user_estimate_max_scheduling_latency(thread_id thread);
68 status_t _user_analyze_scheduling(bigtime_t from, bigtime_t until, void* buffer,
69 	size_t size, struct scheduling_analysis* analysis);
70 
71 #ifdef __cplusplus
72 }
73 #endif
74 
75 
76 /*!	Reschedules, if necessary.
77 	The thread spinlock must be held.
78 */
79 static inline void
80 scheduler_reschedule_if_necessary_locked()
81 {
82 	if (gCPU[smp_get_current_cpu()].invoke_scheduler)
83 		scheduler_reschedule();
84 }
85 
86 
87 /*!	Reschedules, if necessary.
88 	Is a no-op, if interrupts are disabled.
89 */
90 static inline void
91 scheduler_reschedule_if_necessary()
92 {
93 	if (are_interrupts_enabled()) {
94 		cpu_status state = disable_interrupts();
95 		GRAB_THREAD_LOCK();
96 		scheduler_reschedule_if_necessary_locked();
97 		RELEASE_THREAD_LOCK();
98 		restore_interrupts(state);
99 	}
100 }
101 
102 
103 #endif /* KERNEL_SCHEDULER_H */
104