Age | Commit message (Collapse) | Author |
|
Now that there is per-thread work accounting, work scaling can occur less
frequently. Tracking rounds allows directly reusing the work of a thread
on insertion or removal.
|
|
|
|
Dynamic events on time-sharing run queues shouldn't trigger a useless
scheduling attempt when the current thread is a real-time one.
|
|
|
|
|
|
This change adds a new time-shared run queue for expired threads. There is now
per-thread work accounting, potential preemption when waking up threads, and
no linear reset of the run queue when starting a new round. It also prepares
the introduction of thread migration.
|
|
The existing thread_sched_ts_add_scale function is now always used for work
scaling.
|
|
For now, thread_wakeup can only wake up a thread on the same processor
as the caller. This is needed to properly implement thread migration.
|
|
Handling this kind of error makes threading hazardous. It's just way better
to simply consider a thread can always be added to a run queue. The reason
it could fail is that the time-sharing scheduling algorithm doesn't support
a global weight greater than 2^32. A direct implication is that, because of
this limitation, the maximum number of threads should be limited too.
|
|
|
|
The scaled work isn't relative to the thread weight being added or removed,
it's actually the new group work.
|
|
Protecting run queues from concurrent access in addition to interrupts will
be required for inter-processor operations such as thread migration.
|
|
|
|
This is best explained by mentioning that the kernel attempts to provide a
threading API similar to POSIX threads.
|
|
This change introduces scheduling classes, including support for real-time
and time-sharing threads. The real-time class matches the requirements of
the POSIX SCHED_FIFO and SCHED_RR policies. The time-sharing class makes
use of a scheduling algorithm based on group ratio round-robin (GR3) to
provide proportional fairness.
|
|
|
|
|
|
Threads must be initialized in a way that matches the expected state of a non
running thread. In other words, preemption (in addition to interrupts) must be
disabled. Also, set the migration counter.
|
|
This change removes the current thread member from the run queues, and moves
the responsibility of maintaining it to the architecture specific tcb module.
For the x86 architecture, the TCB functions use a per-CPU pointer that can
be read and set in a single instruction, making it interrupt-safe and thus
migration-safe.
|
|
|
|
|
|
There is currently no thread migration, but some modules already need
migration control calls so that they're still valid once migration is
implemented.
|
|
Idle threads are obviously not init-only data.
|
|
|
|
|
|
In practice, this merely means an idle thread now exists for each CPU,
and threads can be preempted and rescheduled on each of them. There is
currently no migration between processors.
|
|
Preemption control is implemented using a thread-local counter. The
global dummy thread structure must be replaced with per-CPU ones, which
will be used later for the idle threads.
|
|
|
|
|
|
|
|
This change adds periodic timer interrupt reporting to the thread
module, basic thread selection, and context switching. It currently
only applies to the main processor. The x86/tcb module has been
drastically simplified as a side effect.
|
|
Three new modules are added :
- kern/task: Tasks are thread groups and resource containers for their
threads.
- kern/thread: The well known scheduling unit.
- x86/tcb: The architecture specific thread control block.
The kernel currently loads a single thread context on the main processor.
|