mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-18 10:46:25 +00:00
lx_emul: adjust start & stop tick behaviour
Do not start and stop idle ticking within the timer interrupt routine, but do it around the whole Lx_kit scheduling, which is always called when Linux code gets active again, either because of backend signals, interrupts, or timing signals. This commit implicitly reverts the (incomplete) solution of issue #4550 Ref genodelabs/genode#4778
This commit is contained in:
parent
b9b18c92d0
commit
2c1724d7f2
@ -44,10 +44,10 @@ void lx_emul_task_name(struct task_struct * task, const char * name);
|
||||
|
||||
void *lx_emul_task_stack(struct task_struct const * task);
|
||||
|
||||
char lx_emul_task_another_runnable(void);
|
||||
|
||||
void lx_emul_task_mark_for_removal(struct task_struct const * task);
|
||||
|
||||
void lx_emul_task_set_idle(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -31,13 +31,18 @@ class Lx_kit::Scheduler
|
||||
|
||||
List<Task> _present_list { };
|
||||
Task * _current { nullptr };
|
||||
Task * _idle { nullptr };
|
||||
|
||||
Genode::Entrypoint &ep;
|
||||
|
||||
void _idle_pre_post_process();
|
||||
|
||||
public:
|
||||
|
||||
Task & current();
|
||||
|
||||
void idle(Task & idle) { _idle = &idle; }
|
||||
|
||||
bool active() const;
|
||||
|
||||
void add(Task & task);
|
||||
@ -47,8 +52,6 @@ class Lx_kit::Scheduler
|
||||
void unblock_irq_handler();
|
||||
void unblock_time_handler();
|
||||
|
||||
bool another_runnable(Task *);
|
||||
|
||||
Task & task(void * t);
|
||||
|
||||
template <typename FN>
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/irqchip.h>
|
||||
#include <linux/tick.h>
|
||||
#include <../kernel/irq/internals.h>
|
||||
|
||||
static int dde_irq_set_wake(struct irq_data *d, unsigned int on)
|
||||
@ -173,9 +172,6 @@ int lx_emul_irq_task_function(void * data)
|
||||
if (!dde_irq_domain)
|
||||
continue;
|
||||
|
||||
/* check restarting ticking which may stopped in idle task */
|
||||
tick_nohz_idle_restart_tick();
|
||||
|
||||
irq_enter();
|
||||
|
||||
irq = irq_find_mapping(dde_irq_domain, lx_emul_irq_last());
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include <lx_emul/irq.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/irqchip.h>
|
||||
#include <linux/tick.h>
|
||||
#include <../kernel/irq/internals.h>
|
||||
|
||||
|
||||
@ -53,9 +52,6 @@ int lx_emul_irq_task_function(void * data)
|
||||
for (;;) {
|
||||
lx_emul_task_schedule(true);
|
||||
|
||||
/* check restarting ticking which may stopped in idle task */
|
||||
tick_nohz_idle_restart_tick();
|
||||
|
||||
irq_enter();
|
||||
|
||||
irq = lx_emul_irq_last();
|
||||
|
@ -69,22 +69,40 @@ static int kernel_init(void * args)
|
||||
}
|
||||
|
||||
|
||||
static void timer_loop(void)
|
||||
static int kernel_idle(void * args)
|
||||
{
|
||||
for (;;) {
|
||||
tick_nohz_idle_enter();
|
||||
struct task_struct *tsk = current;
|
||||
set_task_comm(tsk, "idle");
|
||||
|
||||
if (!lx_emul_task_another_runnable())
|
||||
/* set this current task to be the idle task */
|
||||
lx_emul_task_set_idle();
|
||||
|
||||
/*
|
||||
* Idle task always gets run in the end of each schedule
|
||||
* and again at the beginning of each schedule
|
||||
*/
|
||||
for (;;) {
|
||||
lx_emul_task_schedule(true);
|
||||
|
||||
tick_nohz_idle_enter();
|
||||
tick_nohz_idle_stop_tick();
|
||||
|
||||
lx_emul_task_schedule(true);
|
||||
lx_emul_time_handle();
|
||||
|
||||
/* check restarting ticking */
|
||||
tick_nohz_idle_restart_tick();
|
||||
|
||||
tick_nohz_idle_exit();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void timer_loop(void)
|
||||
{
|
||||
for (;;) {
|
||||
lx_emul_task_schedule(true);
|
||||
lx_emul_time_handle();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -125,6 +143,7 @@ int lx_emul_init_task_function(void * dtb)
|
||||
sched_clock_init();
|
||||
|
||||
kernel_thread(kernel_init, NULL, CLONE_FS);
|
||||
kernel_thread(kernel_idle, NULL, CLONE_FS);
|
||||
pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
|
||||
kthreadd_task = find_task_by_pid_ns(pid, NULL);;
|
||||
|
||||
|
@ -102,15 +102,13 @@ extern "C" void * lx_emul_task_stack(struct task_struct const * t)
|
||||
}
|
||||
|
||||
|
||||
extern "C" char lx_emul_task_another_runnable()
|
||||
{
|
||||
Lx_kit::Task & task = Lx_kit::env().scheduler.current();
|
||||
|
||||
return Lx_kit::env().scheduler.another_runnable(&task);
|
||||
}
|
||||
|
||||
|
||||
extern "C" void lx_emul_task_mark_for_removal(struct task_struct const *t)
|
||||
{
|
||||
Lx_kit::env().scheduler.task((void*)t).mark_for_destruction();
|
||||
}
|
||||
|
||||
|
||||
extern "C" void lx_emul_task_set_idle(void)
|
||||
{
|
||||
return Lx_kit::env().scheduler.idle(Lx_kit::env().scheduler.current());
|
||||
}
|
||||
|
@ -27,6 +27,16 @@
|
||||
using namespace Genode;
|
||||
using namespace Lx_kit;
|
||||
|
||||
void Scheduler::_idle_pre_post_process()
|
||||
{
|
||||
if (!_idle)
|
||||
return;
|
||||
|
||||
_current = _idle;
|
||||
_idle->run();
|
||||
}
|
||||
|
||||
|
||||
Task & Scheduler::current()
|
||||
{
|
||||
if (!_current) {
|
||||
@ -104,6 +114,8 @@ void Scheduler::schedule()
|
||||
Genode::sleep_forever();
|
||||
}
|
||||
|
||||
_idle_pre_post_process();
|
||||
|
||||
/*
|
||||
* Iterate over all tasks and run first runnable.
|
||||
*
|
||||
@ -116,9 +128,6 @@ void Scheduler::schedule()
|
||||
while (true) {
|
||||
bool at_least_one = false;
|
||||
|
||||
/* update jiffies before running task */
|
||||
//Lx::timer_update_jiffies();
|
||||
|
||||
for (Task * t = _present_list.first(); t; ) {
|
||||
|
||||
Task *tmp = t;
|
||||
@ -148,23 +157,8 @@ void Scheduler::schedule()
|
||||
break;
|
||||
}
|
||||
|
||||
_idle_pre_post_process();
|
||||
|
||||
/* clear current as no task is running */
|
||||
_current = nullptr;
|
||||
}
|
||||
|
||||
|
||||
bool Scheduler::another_runnable(Task * skip)
|
||||
{
|
||||
for (Task * t = _present_list.first(); t; t = t->next()) {
|
||||
|
||||
if (!t->runnable())
|
||||
continue;
|
||||
|
||||
if (skip && t == skip)
|
||||
continue;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
return false;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user