xref: /haiku/src/system/kernel/scheduler/scheduler_locking.h (revision 9642f7705b27e5c270c15fa526d14e1848c2c27d)
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:
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 
31 typedef AutoLocker<CPUEntry, CPURunQueueLocking> CPURunQueueLocker;
32 
33 
34 class CoreRunQueueLocking {
35 public:
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 
48 typedef AutoLocker<CoreEntry, CoreRunQueueLocking> CoreRunQueueLocker;
49 
50 class CoreCPUHeapLocking {
51 public:
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 
64 typedef AutoLocker<CoreEntry, CoreCPUHeapLocking> CoreCPUHeapLocker;
65 
66 class SchedulerModeLocking {
67 public:
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 
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:
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 
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:
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 
143 class InterruptsBigSchedulerLocker :
144 	public AutoLocker<int, InterruptsBigSchedulerLocking> {
145 public:
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