Commit Graph

48019 Commits

Author SHA1 Message Date
Pawel Dziepak
5cbf227236 kernel/util: Allocate only one array in MinMaxHeap 2013-10-20 23:33:55 +02:00
Pawel Dziepak
a6d4233e59 scheduler_affine: Choose wisely which core to wake up
The longer core is idle the deeper idle state it has entered. That's
why the scheduler should always choose the core that has gone idle
most recently (both for performance and power saving reasons).

Moreover, if there are more than one package the scheduler should
minimize the number of packages with at least one core active when
power saving is the priority. Contrary, as many packages as possible
should be used when aiming for high performance.
2013-10-20 23:26:32 +02:00
Pawel Dziepak
da3a48f4a8 scheduler_affine: Use min-max heap as per-core CPU heap 2013-10-17 19:23:27 +02:00
Pawel Dziepak
18c0d163ed kernel/util: Add MinMaxHeap implementation 2013-10-17 19:22:29 +02:00
Pawel Dziepak
278c9784a1 scheduler_affine: Use global core heap and per-core CPU heaps
There is a global heap of cores, where the key is the highest priority
of threads running on that core. Moreover, for each core there is
a heap of logical processors on this core where the key is the priority
of currently running thread.

The per-core heap is used for load balancing among logical processors
on that core. The global heap is used in initial decision where to put
the thread (note that the algorithm that makes this decision is not
complete yet).
2013-10-17 02:11:28 +02:00
Pawel Dziepak
3ec1d8da42 scheduler_affine: Add logic shared with simple scheduler
The scheduler is in very early stage. There is no thread migration and
the algorithms choosing CPU for thread are very simple.

Since affine scheduler is going to use one run queue per core simple on
single core machines it will work exactly the same as simple scheduler.
That would allow us to have only one scheduler implementation usable
on all kinds of machines.
2013-10-16 23:50:18 +02:00
Pawel Dziepak
824ed26c51 kernel: Fully detect CPU topology before initializing scheduler 2013-10-16 20:02:56 +02:00
Pawel Dziepak
cf863a5040 kernel: Decide whether to use simple or affine scheduler
Simple scheduler is used when we do not have to worry about cache affinity
(i.e. single core with or without SMT, multicore with all cache levels
shared).

When we replace gSchedulerLock with more fine grained locking affine
scheduler should also be chosen when logical CPU count is high (regardless
of cache).
2013-10-16 18:39:25 +02:00
Pawel Dziepak
ebec24f9e0 kernel: Add support for disabling CPUs in scheduler 2013-10-15 02:02:54 +02:00
Pawel Dziepak
3de2c5ceec kernel: Add support for pinned threads 2013-10-15 01:47:28 +02:00
Pawel Dziepak
51d1e9ada0 kernel: Remove scheduler_simple_smp 2013-10-15 00:37:19 +02:00
Pawel Dziepak
f20ad54be2 kernel: Add support for SMP systems to simple scheduler
In SMP systems simple scheduler will be used only when all logical
processors share all levels of cache and the number of CPUs is low.
In such systems we do not have to care about cache affinity and
the contention on the lock protecting shared run queue is low. Single
run queue makes load balancing very simple.
2013-10-15 00:29:04 +02:00
Pawel Dziepak
298314fe4b libroot: Update sched_get_priority_{max, min}()
SCHED_RR is a real-time scheduling policy.
SCHED_FIFO and SCHED_SPORADIC are not supported (at least for now).
2013-10-09 20:57:42 +02:00
Pawel Dziepak
29e65827fd kernel: Remove possibility to yield to all threads
Kernel support for yielding to all (including lower priority) threads
has been removed. POSIX sched_yield() remains unchanged.

If a thread really needs to yield to everyone it can reduce its priority
to the lowest possible and then yield (it will then need to manually
return to its prvious priority upon continuing).
2013-10-09 20:42:34 +02:00
Pawel Dziepak
fee8009184 kernel: Add another penalty for CPU bound threads
Each thread has its minimal priority that depends on the static priority.
However, it is still able to starve threads with even lower priority
(e.g. CPU bound threads with lower static priority). To prevent this
another penalty is introduced. When the minimal priority is reached
penalty (count mod minimal_priority) is added, where count is the number
of time slices since the thread reached its minimal priority. This prevents
starvation of lower priorirt threads (since all CPU bound threads may have
their priority temporaily reduced to 1) but preserves relation between
static priorities - when there are two CPU bound threads the one with
higher static priority would get more CPU time.
2013-10-09 20:13:47 +02:00
Pawel Dziepak
4ade765cab kernel/util: Add heap implementation 2013-10-09 04:26:09 +02:00
Pawel Dziepak
24dbeeddb2 kernel: Give longer time slice to lower priority threads 2013-10-09 02:25:21 +02:00
Pawel Dziepak
a2bdd2842f kernel: Add scheduler_op for dumping thread data 2013-10-09 02:08:49 +02:00
Pawel Dziepak
3e91b082c8 libroot: Do not rely on thread_yield() 2013-10-09 02:07:08 +02:00
Pawel Dziepak
879ceb60d8 kernel: Remove suporfluous casts 2013-10-09 01:45:07 +02:00
Pawel Dziepak
130000e068 kernel: Dump scheduler specific thread data 2013-10-09 01:37:00 +02:00
Pawel Dziepak
f256b4aca7 kernel: Use SimpleRunQueue as run queue type everywhere 2013-10-09 01:20:40 +02:00
Pawel Dziepak
0896565a6e kernel: Support sched_yield() properly
sched_yield() should not yield to the threads with lower priority.
2013-10-09 01:18:55 +02:00
Pawel Dziepak
ee69e53630 kernel: Minor improvements, separate priority and yield logic 2013-10-08 21:36:49 +02:00
Pawel Dziepak
9363e99b19 kernel: Remove Thread::next_priority 2013-10-08 20:21:35 +02:00
Pawel Dziepak
346e789a21 kernel: Fix style issues 2013-10-08 20:15:21 +02:00
Pawel Dziepak
94f4574d78 kernel: Move thread retrieving code to separate function 2013-10-08 20:13:10 +02:00
Pawel Dziepak
03e3a82953 kernel: Allow threads to yield CPU properly 2013-10-08 06:41:20 +02:00
Pawel Dziepak
bab69bdb47 kernel: Force high priority threads to yield less often 2013-10-08 04:53:30 +02:00
Pawel Dziepak
547b8c76c7 kernel: Cancel penalty only if the thread actually waits
Require the thread to give up CPU for at least one time slice before
cancelling its penalty.
2013-10-08 04:50:23 +02:00
Pawel Dziepak
21808e8f0b kernel: Limit maximum priority penalty
The maximum penalty the thread can receive is now limited depending on
the real thread priority. However, since it make it possible to starve
threads with priority lower than that limit. To prevent that threads
that have already earned the maximum penalty are periodically forced
to yield CPU to all other threads.
2013-10-08 02:54:58 +02:00
Pawel Dziepak
4cba4ff1df kernel/util: Use private/kernel/debug.h 2013-10-08 01:36:30 +02:00
Pawel Dziepak
31e65090db kernel: Use standard compliant version of variadic macros 2013-10-08 01:34:55 +02:00
Pawel Dziepak
e083bca041 kernel: Allow threads to always finish their time slice
Until now, when the thread has been preempted by higher priority
thread it was then placed at the end of its priority FIFO and given
a new time slice. This patch changes it allowing the thread to
complete its time slice (when the higher priority threads are done),
unless there was very little time left in which case this time is added
to the next time slice.

Apart from making the algorithm more fair this change allows to identify
CPU bound threads more easily. (Earlier they could 'hide' by being
preempted by higher priority thread and consequently never using
their whole time slice).
2013-10-08 01:08:05 +02:00
Pawel Dziepak
565e7a977d kernel: Update SchedulerTracing::EnqueueThread 2013-10-07 21:52:45 +02:00
Pawel Dziepak
72f844835e kernel: Do not require double parentheses in TRACE statements. 2013-10-07 21:29:10 +02:00
Pawel Dziepak
82c26e1f1f kernel: Punish CPU bound threads
This patch appears to fix #8007.

Thread that consume its whole quantum has its priority reduced. The penalty
is cancelled when the thread voluntarily gives up CPU. Real-time threads
are not affected.

The problem of thread starvation is not solved completely. The worst case
latency is still unbounded (even in systems with bounded number of threads).
When a middle priority thread is constantly preempted by high priority
threads it would not earn the penalty, thus the lower priority threads
still can be starved. Moreover, the punishment is probably too aggressive
as it reduces priority of virtually all CPU bound threads to 1.
2013-10-07 21:11:32 +02:00
Pawel Dziepak
6d7e291233 kernel: Allow scheduler initialization to fail 2013-10-05 20:45:07 +02:00
Pawel Dziepak
9ad558f01c kernel: Use the new runqueue in non-MP scheduler 2013-10-05 20:22:59 +02:00
Pawel Dziepak
b8c1df9b00 kernel: Add O(1) lookup and insertion priority queue 2013-10-05 20:16:06 +02:00
Pawel Dziepak
7039b950fb x86[_64]: Fix style issues 2013-10-05 18:03:00 +02:00
Pawel Dziepak
149c82a8ec kernel/util: Add bitmap implementation 2013-10-03 04:27:49 +02:00
Pawel Dziepak
7087b865e2 x86[_64]: Remove superfluous memset()s 2013-10-03 04:26:21 +02:00
Pawel Dziepak
36cc64a9b3 x86[_64]: Add CPU cache topology detection for AMD and Intel CPUs 2013-10-02 23:48:03 +02:00
Pawel Dziepak
1f50d09018 kernel/util: Add bit hack utilities 2013-10-02 21:24:46 +02:00
Pawel Dziepak
26c3861891 x86[_64]: Fix some style issues 2013-10-02 21:18:56 +02:00
Pawel Dziepak
fa6f78aee7 x86[_64]: Use uint32 for maximum CPUID leaf number 2013-10-02 21:03:34 +02:00
Pawel Dziepak
c9b6f27d94 x86[_64]: Add CPU topology detection for AMD processors 2013-10-02 02:34:35 +02:00
Pawel Dziepak
f1644d9d0b x86[_64]: Set level shift by counting bits in mask 2013-10-02 01:55:07 +02:00
Pawel Dziepak
fafeda52ea x86[_64]: Do not return too soon from detectCPUTopology() 2013-10-02 01:49:10 +02:00