hw: implement priority-based scheduling (fix #945)

This commit is contained in:
Stefan Kalkowski 2013-11-11 16:55:30 +01:00 committed by Norman Feske
parent 1953acae77
commit 265ec48c20
7 changed files with 91 additions and 18 deletions

View File

@ -52,6 +52,7 @@ namespace Genode {
Ram_dataspace_capability _utcb;
char _name[NAME_MAX_LEN];
char _kernel_thread[sizeof(Kernel::Thread)];
unsigned _priority;
/*
* Wether this thread is the main thread of a program.
@ -196,6 +197,8 @@ namespace Genode {
bool main_thread() const { return _main_thread; }
Tlb * tlb() const { return _tlb; }
unsigned priority() { return _priority; }
};
}

View File

@ -125,7 +125,11 @@ namespace Kernel
*/
Vm(Genode::Cpu_state_modes * const state,
Signal_context * const context)
: _state(state), _context(context) { }
: _state(state), _context(context)
{
/* set VM to least priority by now */
priority = 0;
}
/**************************

View File

@ -0,0 +1,46 @@
/*
* \brief Priority definition for scheduling
* \author Stefan Kalkowski
* \date 2013-11-08
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _KERNEL__PRIORITY_H_
#define _KERNEL__PRIORITY_H_
#include <util/misc_math.h>
namespace Kernel
{
class Priority;
}
class Kernel::Priority
{
private:
unsigned _prio;
public:
enum { MAX = 255 };
Priority(unsigned prio = MAX) : _prio(Genode::min(prio, MAX)) { }
Priority &operator=(unsigned const &prio)
{
_prio = Genode::min(prio, MAX);
return *this;
}
operator unsigned() const { return _prio; }
};
#endif /* _KERNEL__PRIORITY_H_ */

View File

@ -15,6 +15,7 @@
#define _KERNEL__SCHEDULER_H_
/* core includes */
#include <kernel/priority.h>
#include <assert.h>
namespace Kernel
@ -155,34 +156,44 @@ class Kernel::Scheduler
/**
* Capability to be item in a scheduler through inheritance
*/
class Item : public Double_list<T>::Item { };
struct Item : public Double_list<T>::Item
{
Priority priority;
};
protected:
T * const _idle;
Double_list<T> _items;
T * _current;
Double_list<T> _items[Priority::MAX+1];
public:
/**
* Constructor
*/
Scheduler(T * const idle) : _idle(idle) { }
Scheduler(T * const idle) : _idle(idle), _current(0) { }
/**
* Get currently scheduled item
*/
T * head() const
T * head()
{
T * const i = _items.head();
if (i) { return i; }
for (int i = Priority::MAX; i >= 0 ; i--) {
_current = _items[i].head();
if (_current) return _current;
}
return _idle;
}
/**
* End turn of currently scheduled item
*/
void yield() { _items.head_to_tail(); }
void yield()
{
if (!_current) return;
_items[_current->priority].head_to_tail();
}
/**
* Include 'i' in scheduling
@ -190,13 +201,13 @@ class Kernel::Scheduler
void insert(T * const i)
{
assert(i != _idle);
_items.insert_tail(i);
_items[i->priority].insert_tail(i);
}
/**
* Exclude 'i' from scheduling
*/
void remove(T * const i) { _items.remove(i); }
void remove(T * const i) { _items[i->priority].remove(i); }
};
#endif /* _KERNEL__SCHEDULER_H_ */

View File

@ -75,3 +75,13 @@ Kernel::Thread::prepare_to_start(void * const ip,
this->pd_id(), pd_label(), id(), label());
}
}
Kernel::Thread::Thread(Platform_thread * const platform_thread)
: _platform_thread(platform_thread), _state(AWAIT_START),
_pager(0), _pd_id(0), _phys_utcb(0), _virt_utcb(0),
_signal_receiver(0)
{
priority = _platform_thread ? _platform_thread->priority()
: Kernel::Priority::MAX;
}

View File

@ -309,12 +309,7 @@ class Kernel::Thread
*
* \param platform_thread userland backend of execution context
*/
Thread(Platform_thread * const platform_thread)
:
_platform_thread(platform_thread), _state(AWAIT_START),
_pager(0), _pd_id(0), _phys_utcb(0), _virt_utcb(0),
_signal_receiver(0)
{ }
Thread(Platform_thread * const platform_thread);
/**
* Return wether the thread is a core thread

View File

@ -77,7 +77,9 @@ Platform_thread::Platform_thread(const char * name,
size_t const stack_size, unsigned const pd_id)
:
_thread_base(thread_base), _stack_size(stack_size),
_pd_id(pd_id), _rm_client(0), _virt_utcb(0), _main_thread(0)
_pd_id(pd_id), _rm_client(0), _virt_utcb(0),
_priority(Kernel::Priority::MAX),
_main_thread(0)
{
strncpy(_name, name, NAME_MAX_LEN);
@ -100,7 +102,9 @@ Platform_thread::Platform_thread(const char * name, unsigned int priority,
addr_t utcb)
:
_thread_base(0), _stack_size(0), _pd_id(0), _rm_client(0),
_virt_utcb((Native_utcb *)utcb), _main_thread(0)
_virt_utcb((Native_utcb *)utcb),
_priority(Cpu_session::scale_priority(Kernel::Priority::MAX, priority)),
_main_thread(0)
{
strncpy(_name, name, NAME_MAX_LEN);