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