Project HW #2

This commit is contained in:
Claudio Maggioni 2020-03-30 19:21:24 +02:00
parent 7bb6e7cbc0
commit 45efb57647
3 changed files with 124 additions and 64 deletions

View file

@ -1,3 +1,6 @@
// Author: Claudio Maggioni
// Author: Tommaso Rodolfo Masera
#include "devices/timer.h"
#include <debug.h>
#include <inttypes.h>
@ -7,6 +10,8 @@
#include "threads/interrupt.h"
#include "threads/synch.h"
#include "threads/thread.h"
#include "threads/malloc.h"
#include "../lib/kernel/list.h"
/* See [8254] for hardware details of the 8254 timer chip. */
@ -89,11 +94,12 @@ timer_elapsed (int64_t then)
void
timer_sleep (int64_t ticks)
{
int64_t start = timer_ticks ();
if (ticks <= 0)
return;
ASSERT (intr_get_level() == INTR_ON);
while (timer_elapsed (start) < ticks)
thread_yield ();
thread_sleep(ticks);
}
/* Sleeps for approximately MS milliseconds. Interrupts must be
@ -171,6 +177,8 @@ static void
timer_interrupt (struct intr_frame *args UNUSED)
{
ticks++;
thread_unsleep();
thread_tick();
}

View file

@ -1,3 +1,6 @@
// Author: Claudio Maggioni
// Author: Tommaso Rodolfo Masera
#include "threads/thread.h"
#include <debug.h>
#include <stddef.h>
@ -11,6 +14,7 @@
#include "threads/switch.h"
#include "threads/synch.h"
#include "threads/vaddr.h"
#include "devices/timer.h"
#ifdef USERPROG
#include "userprog/process.h"
#endif
@ -37,6 +41,8 @@ static struct thread *initial_thread;
/* Lock used by allocate_tid(). */
static struct lock tid_lock;
static struct list sleeping;
/* Stack frame for kernel_thread(). */
struct kernel_thread_frame
{
@ -98,6 +104,46 @@ thread_init (void)
init_thread (initial_thread, "main", PRI_DEFAULT);
initial_thread->status = THREAD_RUNNING;
initial_thread->tid = allocate_tid ();
list_init(&sleeping);
}
static bool
earlier_wakeup(const struct list_elem* a, const struct list_elem* b, void* aux UNUSED) {
return list_entry(a, struct thread, elem)->wakeup <
list_entry(b, struct thread, elem)->wakeup;
}
void
thread_sleep(uint64_t ticks) {
enum intr_level old_level = intr_disable();
struct thread* cur = thread_current();
cur->wakeup = timer_ticks() + ticks;
// printf("sleeping insert %X\n", cur);
list_insert_ordered(&sleeping, &(cur->elem), earlier_wakeup, NULL);
thread_block();
intr_set_level(old_level);
}
static struct thread* thr(struct list_elem* l) {
return list_entry(l, struct thread, elem);
}
void
thread_unsleep() {
const uint64_t ticks = timer_ticks();
enum intr_level old_level = intr_disable();
if (!list_empty(&sleeping)) {
struct list_elem* t = list_begin(&sleeping);
while (thr(t)->wakeup <= ticks) {
// printf("sleeping remove %X\n", thr(t));
struct thread* s = thr(t);
t = list_remove(t);
thread_unblock(s);
}
}
intr_set_level(old_level);
}
/* Starts preemptive thread scheduling by enabling interrupts.

View file

@ -1,3 +1,6 @@
// Author: Claudio Maggioni
// Author: Tommaso Rodolfo Masera
#ifndef THREADS_THREAD_H
#define THREADS_THREAD_H
@ -89,7 +92,7 @@ struct thread
uint8_t *stack; /* Saved stack pointer. */
int priority; /* Priority. */
struct list_elem allelem; /* List element for all threads list. */
uint64_t wakeup;
/* Shared between thread.c and synch.c. */
struct list_elem elem; /* List element. */
@ -126,6 +129,9 @@ const char *thread_name (void);
void thread_exit (void) NO_RETURN;
void thread_yield (void);
void thread_sleep(uint64_t ticks);
void thread_unsleep(void);
/* Performs some operation on thread t, given auxiliary data AUX. */
typedef void thread_action_func (struct thread *t, void *aux);
void thread_foreach (thread_action_func *, void *);