mirror of
https://github.com/genodelabs/genode.git
synced 2025-05-11 04:53:04 +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;
|
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; }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**************************
|
/**************************
|
||||||
|
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_
|
#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_ */
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user