1 /* 2 * Copyright 2014, Paweł Dziepak, pdziepak@quarnos.org. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef KERNEL_SCHEDULER_LOCKING_H 6 #define KERNEL_SCHEDULER_LOCKING_H 7 8 9 #include <util/AutoLock.h> 10 11 #include "scheduler_cpu.h" 12 13 14 namespace Scheduler { 15 16 17 class CPURunQueueLocking { 18 public: Lock(CPUEntry * cpu)19 inline bool Lock(CPUEntry* cpu) 20 { 21 cpu->LockRunQueue(); 22 return true; 23 } 24 Unlock(CPUEntry * cpu)25 inline void Unlock(CPUEntry* cpu) 26 { 27 cpu->UnlockRunQueue(); 28 } 29 }; 30 31 typedef AutoLocker<CPUEntry, CPURunQueueLocking> CPURunQueueLocker; 32 33 34 class CoreRunQueueLocking { 35 public: Lock(CoreEntry * core)36 inline bool Lock(CoreEntry* core) 37 { 38 core->LockRunQueue(); 39 return true; 40 } 41 Unlock(CoreEntry * core)42 inline void Unlock(CoreEntry* core) 43 { 44 core->UnlockRunQueue(); 45 } 46 }; 47 48 typedef AutoLocker<CoreEntry, CoreRunQueueLocking> CoreRunQueueLocker; 49 50 class CoreCPUHeapLocking { 51 public: Lock(CoreEntry * core)52 inline bool Lock(CoreEntry* core) 53 { 54 core->LockCPUHeap(); 55 return true; 56 } 57 Unlock(CoreEntry * core)58 inline void Unlock(CoreEntry* core) 59 { 60 core->UnlockCPUHeap(); 61 } 62 }; 63 64 typedef AutoLocker<CoreEntry, CoreCPUHeapLocking> CoreCPUHeapLocker; 65 66 class SchedulerModeLocking { 67 public: Lock(int *)68 bool Lock(int* /* lockable */) 69 { 70 CPUEntry::GetCPU(smp_get_current_cpu())->EnterScheduler(); 71 return true; 72 } 73 Unlock(int *)74 void Unlock(int* /* lockable */) 75 { 76 CPUEntry::GetCPU(smp_get_current_cpu())->ExitScheduler(); 77 } 78 }; 79 80 class SchedulerModeLocker : 81 public AutoLocker<int, SchedulerModeLocking> { 82 public: 83 SchedulerModeLocker(bool alreadyLocked = false, bool lockIfNotLocked = true) 84 : 85 AutoLocker<int, SchedulerModeLocking>(&fDummy, alreadyLocked, 86 lockIfNotLocked) 87 { 88 } 89 90 private: 91 int fDummy; 92 }; 93 94 class InterruptsSchedulerModeLocking { 95 public: Lock(int * lockable)96 bool Lock(int* lockable) 97 { 98 *lockable = disable_interrupts(); 99 CPUEntry::GetCPU(smp_get_current_cpu())->EnterScheduler(); 100 return true; 101 } 102 Unlock(int * lockable)103 void Unlock(int* lockable) 104 { 105 CPUEntry::GetCPU(smp_get_current_cpu())->ExitScheduler(); 106 restore_interrupts(*lockable); 107 } 108 }; 109 110 class InterruptsSchedulerModeLocker : 111 public AutoLocker<int, InterruptsSchedulerModeLocking> { 112 public: 113 InterruptsSchedulerModeLocker(bool alreadyLocked = false, 114 bool lockIfNotLocked = true) 115 : 116 AutoLocker<int, InterruptsSchedulerModeLocking>(&fState, alreadyLocked, 117 lockIfNotLocked) 118 { 119 } 120 121 private: 122 int fState; 123 }; 124 125 class InterruptsBigSchedulerLocking { 126 public: Lock(int * lockable)127 bool Lock(int* lockable) 128 { 129 *lockable = disable_interrupts(); 130 for (int32 i = 0; i < smp_get_num_cpus(); i++) 131 CPUEntry::GetCPU(i)->LockScheduler(); 132 return true; 133 } 134 Unlock(int * lockable)135 void Unlock(int* lockable) 136 { 137 for (int32 i = 0; i < smp_get_num_cpus(); i++) 138 CPUEntry::GetCPU(i)->UnlockScheduler(); 139 restore_interrupts(*lockable); 140 } 141 }; 142 143 class InterruptsBigSchedulerLocker : 144 public AutoLocker<int, InterruptsBigSchedulerLocking> { 145 public: InterruptsBigSchedulerLocker()146 InterruptsBigSchedulerLocker() 147 : 148 AutoLocker<int, InterruptsBigSchedulerLocking>(&fState, false, true) 149 { 150 } 151 152 private: 153 int fState; 154 }; 155 156 157 } // namespace Scheduler 158 159 160 #endif // KERNEL_SCHEDULER_LOCKING_H 161 162