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