diff options
| author | Jake Mannens <jake72360@gmail.com> | 2018-07-31 23:48:38 +1000 |
|---|---|---|
| committer | Jake Mannens <jake72360@gmail.com> | 2018-07-31 23:48:38 +1000 |
| commit | 7babda5d4573d432441a416f880cb8cc8c15b55b (patch) | |
| tree | 65accc145f0d583a0c9f5f4cdd36e592a4bb9ca9 | |
| parent | 5a4038a196887994a09968dc08bee4b11e30c411 (diff) | |
Modified the scheduler so that a HLT instruction is executed if no
runnable task is found. This is a very basic method of putting the CPU
into an idle state to reduce power consumption and heat production. This
method is far from perfect however since when the CPU is woken by a
timer interrupt, the scheduler runs through the entire process table
again regardless of whether any task has become runnable, before putting
the CPU back to sleep. In practice, this basic sleep mechanism reduced
idle CPU usage of the VM from 100% to ~6%, a very effective amount.
Updated the sleep() library function to use the new sys_alarm and
sys_pause system calls. This method works by first registering a dummy
signal handler, setting an alarm and finally calling pause() to put the
process to sleep. When the alarm expires, the dummy signal handler is
called (which returns immediately) and finally, the sleep() call
returns. Note however, that this is a temporary function implemented
poorly since it overwrites any pending alarms as well as the SIGALRM
handler.
| -rw-r--r-- | kernel/sched.c | 3 | ||||
| -rw-r--r-- | lib/time.c | 9 |
2 files changed, 9 insertions, 3 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index 9f955d2..ae2fb38 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -217,6 +217,9 @@ void reschedule(void) { return; } } + + /* if not, then halt the machine */ + __asm__ ("hlt"); } } @@ -1,3 +1,4 @@ +#include <signal.h> #include <time.h> #include <unistd.h> @@ -5,8 +6,10 @@ _syscall0(time_t, time); _syscall1(int, alarm, unsigned int, seconds); -void sleep(time_t t) { - time_t start = time(); +static void sleepsig(int sig) {} - while(time() < start + t); +void sleep(time_t t) { + signal(SIGALRM, &sleepsig); + alarm(t); + pause(); } |
