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 14namespace Scheduler { 15 16 17class CPURunQueueLocking { 18public: 19 inline bool Lock(CPUEntry* cpu) 20 { 21 cpu->LockRunQueue(); 22 return true; 23 } 24 25 inline void Unlock(CPUEntry* cpu) 26 { 27 cpu->UnlockRunQueue(); 28 } 29}; 30 31typedef AutoLocker<CPUEntry, CPURunQueueLocking> CPURunQueueLocker; 32 33 34class CoreRunQueueLocking { 35public: 36 inline bool Lock(CoreEntry* core) 37 { 38 core->LockRunQueue(); 39 return true; 40 } 41 42 inline void Unlock(CoreEntry* core) 43 { 44 core->UnlockRunQueue(); 45 } 46}; 47 48typedef AutoLocker<CoreEntry, CoreRunQueueLocking> CoreRunQueueLocker; 49 50class CoreCPUHeapLocking { 51public: 52 inline bool Lock(CoreEntry* core) 53 { 54 core->LockCPUHeap(); 55 return true; 56 } 57 58 inline void Unlock(CoreEntry* core) 59 { 60 core->UnlockCPUHeap(); 61 } 62}; 63 64typedef AutoLocker<CoreEntry, CoreCPUHeapLocking> CoreCPUHeapLocker; 65 66class SchedulerModeLocking { 67public: 68 bool Lock(int* /* lockable */) 69 { 70 CPUEntry::GetCPU(smp_get_current_cpu())->EnterScheduler(); 71 return true; 72 } 73 74 void Unlock(int* /* lockable */) 75 { 76 CPUEntry::GetCPU(smp_get_current_cpu())->ExitScheduler(); 77 } 78}; 79 80class SchedulerModeLocker : 81 public AutoLocker<int, SchedulerModeLocking> { 82public: 83 SchedulerModeLocker(bool alreadyLocked = false, bool lockIfNotLocked = true) 84 : 85 AutoLocker<int, SchedulerModeLocking>(&fDummy, alreadyLocked, 86 lockIfNotLocked) 87 { 88 } 89 90private: 91 int fDummy; 92}; 93 94class InterruptsSchedulerModeLocking { 95public: 96 bool Lock(int* lockable) 97 { 98 *lockable = disable_interrupts(); 99 CPUEntry::GetCPU(smp_get_current_cpu())->EnterScheduler(); 100 return true; 101 } 102 103 void Unlock(int* lockable) 104 { 105 CPUEntry::GetCPU(smp_get_current_cpu())->ExitScheduler(); 106 restore_interrupts(*lockable); 107 } 108}; 109 110class InterruptsSchedulerModeLocker : 111 public AutoLocker<int, InterruptsSchedulerModeLocking> { 112public: 113 InterruptsSchedulerModeLocker(bool alreadyLocked = false, 114 bool lockIfNotLocked = true) 115 : 116 AutoLocker<int, InterruptsSchedulerModeLocking>(&fState, alreadyLocked, 117 lockIfNotLocked) 118 { 119 } 120 121private: 122 int fState; 123}; 124 125class InterruptsBigSchedulerLocking { 126public: 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 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 143class InterruptsBigSchedulerLocker : 144 public AutoLocker<int, InterruptsBigSchedulerLocking> { 145public: 146 InterruptsBigSchedulerLocker() 147 : 148 AutoLocker<int, InterruptsBigSchedulerLocking>(&fState, false, true) 149 { 150 } 151 152private: 153 int fState; 154}; 155 156 157} // namespace Scheduler 158 159 160#endif // KERNEL_SCHEDULER_LOCKING_H 161 162