mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-21 02:01:38 +00:00
hw: implement priority-based scheduling (fix #945)
This commit is contained in:
parent
1953acae77
commit
265ec48c20
@ -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; }
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
/**************************
|
||||
|
46
base-hw/src/core/kernel/priority.h
Normal file
46
base-hw/src/core/kernel/priority.h
Normal 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_ */
|
@ -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_ */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user