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

View File

@ -125,7 +125,11 @@ namespace Kernel
*/ */
Vm(Genode::Cpu_state_modes * const state, Vm(Genode::Cpu_state_modes * const state,
Signal_context * const context) 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_ #define _KERNEL__SCHEDULER_H_
/* core includes */ /* core includes */
#include <kernel/priority.h>
#include <assert.h> #include <assert.h>
namespace Kernel namespace Kernel
@ -155,34 +156,44 @@ class Kernel::Scheduler
/** /**
* Capability to be item in a scheduler through inheritance * 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: protected:
T * const _idle; T * const _idle;
Double_list<T> _items; T * _current;
Double_list<T> _items[Priority::MAX+1];
public: public:
/** /**
* Constructor * Constructor
*/ */
Scheduler(T * const idle) : _idle(idle) { } Scheduler(T * const idle) : _idle(idle), _current(0) { }
/** /**
* Get currently scheduled item * Get currently scheduled item
*/ */
T * head() const T * head()
{ {
T * const i = _items.head(); for (int i = Priority::MAX; i >= 0 ; i--) {
if (i) { return i; } _current = _items[i].head();
if (_current) return _current;
}
return _idle; return _idle;
} }
/** /**
* End turn of currently scheduled item * 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 * Include 'i' in scheduling
@ -190,13 +201,13 @@ class Kernel::Scheduler
void insert(T * const i) void insert(T * const i)
{ {
assert(i != _idle); assert(i != _idle);
_items.insert_tail(i); _items[i->priority].insert_tail(i);
} }
/** /**
* Exclude 'i' from scheduling * 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_ */ #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()); 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 * \param platform_thread userland backend of execution context
*/ */
Thread(Platform_thread * const platform_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)
{ }
/** /**
* Return wether the thread is a core 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) size_t const stack_size, unsigned const pd_id)
: :
_thread_base(thread_base), _stack_size(stack_size), _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); strncpy(_name, name, NAME_MAX_LEN);
@ -100,7 +102,9 @@ Platform_thread::Platform_thread(const char * name, unsigned int priority,
addr_t utcb) addr_t utcb)
: :
_thread_base(0), _stack_size(0), _pd_id(0), _rm_client(0), _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); strncpy(_name, name, NAME_MAX_LEN);