Compare commits

..

25 Commits

Author SHA1 Message Date
1e09712cc2 fix mlfqs tests, complete BSD scheduling 2024-10-17 02:38:57 +01:00
c767cfe159 Ignore thread_set_priority when BSD enabled 2024-10-16 22:58:03 +01:00
eacd93b32d Optimise load_avg and recent_cpu updates
- only run when BSD scheduler is enabled
2024-10-16 22:56:47 +01:00
de8f303fa2 Implement BSD calculations
- load_avg, recent_cpu, priority calculations
- reduce frac bits to 14
2024-10-16 22:50:46 +01:00
5967257bb0 Fix fixed-point returns 2024-10-16 19:48:08 +01:00
EDiasAlberto
4a5de13d1e implement recent_cpu calculations on every second 2024-10-16 18:45:28 +01:00
EDiasAlberto
7a1aa21e1e implement logic to increment recent_cpu on every timer_interrupt () call 2024-10-16 18:34:56 +01:00
EDiasAlberto
0db3551a9a implement behaviour for thread recent_cpu to be defined based on parent recent_cpu, 0 for initial thread 2024-10-16 18:27:21 +01:00
Dias Alberto, Ethan
96fa718be1 Merge branch 'BSD-merged' into 'ethan-BSD'
Bring personal branch up to date

See merge request lab2425_autumn/pintos_22!5
2024-10-16 17:03:17 +00:00
Dias Alberto, Ethan
51d208f3ef Merge branch 'gleb/BSD' into 'BSD-merged'
Merge rewritten inline funcs into main BSD repo

See merge request lab2425_autumn/pintos_22!4
2024-10-16 17:02:13 +00:00
63742c5717 implement thread_get_nice & thread_get_recent_cpu 2024-10-15 19:56:46 +01:00
27d564ab49 inline funcs instead of macros for fixed-point 2024-10-15 19:45:11 +01:00
EDiasAlberto
efed660968 implement thread_set_nice and make skeleton for calculate_priority 2024-10-15 19:25:02 +01:00
EDiasAlberto
ab66551c06 implement thread_get_nice 2024-10-15 19:21:15 +01:00
EDiasAlberto
3e379acd5e modify gitignore to ignore vscode files 2024-10-15 17:27:16 +01:00
EDiasAlberto
2834af032d fix bracketing issue in ROUNDING_FP_TO_INT 2024-10-15 17:23:03 +01:00
EDiasAlberto
df89bda71e modify thread struct to track thread niceness and recent_cpu time 2024-10-15 17:09:06 +01:00
EDiasAlberto
5178b72370 comment fixed point arithmetic header 2024-10-15 15:34:06 +01:00
EDiasAlberto
724b6065f7 implement macros for fp multiplication and division 2024-10-15 15:24:34 +01:00
EDiasAlberto
1f1ffe4470 add brackets to fixed-point conversion_const calculation for clarity 2024-10-15 15:15:16 +01:00
EDiasAlberto
42b0ff9d17 define basic fixed-point arithmetic operations 2024-10-15 15:13:40 +01:00
EDiasAlberto
4e271ea5ab rewrite fixed-point.h to not have magic numbers 2024-10-15 15:04:26 +01:00
EDiasAlberto
4f6849c4a4 fix gitignore formatting 2024-10-15 14:59:57 +01:00
EDiasAlberto
1eb9abfdcd update gitignore to remove CLion files 2024-10-15 14:58:35 +01:00
EDiasAlberto
1042295e5f define fixed point arithmetic constants 2024-10-15 14:57:37 +01:00
5 changed files with 219 additions and 154 deletions

10
.gitignore vendored
View File

@@ -4,13 +4,6 @@
#ignore pdf files (just keep source files) #ignore pdf files (just keep source files)
*.pdf *.pdf
#ignore Mac OS generated files
.DS_Store
#ignore code editor generated directories
.idea
.vscode
#ignore junk files from latex output #ignore junk files from latex output
*.out *.out
*.log *.log
@@ -31,3 +24,6 @@
*.nav *.nav
*.toc *.toc
#ignore files from CLion/VSCode IDEs
.idea
.vscode

95
src/threads/fixed-point.h Normal file
View File

@@ -0,0 +1,95 @@
#include <stdint.h>
#ifndef FIXED_POINT_H
#define FIXED_POINT_H
typedef struct
{
int32_t raw;
} fp32_t;
/* Fixed Point Arithmetic bit count constants */
#define NUM_FRAC_BITS 14
#define NUM_INT_BITS (31 - NUM_FRAC_BITS)
#define CONVERSION_CONST (1 << NUM_FRAC_BITS) /* f = 2^q, (2^20) */
/* Fixed Point Arithmetic conversion operations */
/* Converts an integer n to a fixed point number */
inline fp32_t
int_to_fp (int32_t n)
{
return (fp32_t){ n * CONVERSION_CONST };
}
/* Handles conversion of fixed point to integer. First version truncates, second one rounds */
inline int32_t
fp_floor (fp32_t x)
{
return x.raw / CONVERSION_CONST;
}
inline int32_t
fp_round (fp32_t x)
{
if (x.raw >= 0)
return (x.raw + CONVERSION_CONST / 2) / CONVERSION_CONST;
else
return (x.raw - CONVERSION_CONST / 2) / CONVERSION_CONST;
}
/* Add two fixed points */
inline fp32_t
fp_add (fp32_t x, fp32_t y)
{
return (fp32_t){ x.raw + y.raw };
}
/* Subtract two fixed points */
inline fp32_t
fp_sub (fp32_t x, fp32_t y)
{
return (fp32_t){ x.raw - y.raw };
}
/* Add fixed point to integer */
inline fp32_t
fp_add_int (fp32_t x, int32_t n)
{
return (fp32_t){ x.raw + n * CONVERSION_CONST };
}
/* Subtract integer from fixed point */
inline fp32_t
fp_sub_int (fp32_t x, int32_t n)
{
return (fp32_t){ x.raw - n * CONVERSION_CONST };
}
/* Multiple two fixed points */
inline fp32_t
fp_mul (fp32_t x, fp32_t y)
{
return (fp32_t){ ((int64_t)x.raw) * y.raw / CONVERSION_CONST };
}
/* Divide two fixed points */
inline fp32_t
fp_div (fp32_t x, fp32_t y)
{
return (fp32_t){ ((int64_t)x.raw) * CONVERSION_CONST / y.raw };
}
/* Multiply fixed point and integer */
inline fp32_t
fp_mul_int (fp32_t x, int32_t n)
{
return (fp32_t){ x.raw * n };
}
/* Divide fixed point by integer */
inline fp32_t
fp_div_int (fp32_t x, int32_t n)
{
return (fp32_t){ x.raw / n };
}
#endif //FIXED_POINT_H

View File

@@ -68,8 +68,7 @@ sema_down (struct semaphore *sema)
old_level = intr_disable (); old_level = intr_disable ();
while (sema->value == 0) while (sema->value == 0)
{ {
list_insert_ordered(&sema->waiters, &thread_current ()->elem, list_push_back (&sema->waiters, &thread_current ()->elem);
priority_more, NULL);
thread_block (); thread_block ();
} }
sema->value--; sema->value--;
@@ -114,22 +113,11 @@ sema_up (struct semaphore *sema)
ASSERT (sema != NULL); ASSERT (sema != NULL);
old_level = intr_disable (); old_level = intr_disable ();
if (!list_empty (&sema->waiters))
/* Wake up (unblock) the highest priority thread from the waiters list */ thread_unblock (list_entry (list_pop_front (&sema->waiters),
struct thread *t = NULL; struct thread, elem));
if (!list_empty (&sema->waiters))
{
t = list_entry (list_pop_front (&sema->waiters), struct thread, elem);
thread_unblock (t);
}
sema->value++; sema->value++;
intr_set_level (old_level); intr_set_level (old_level);
/* If the unblocked thread has higher priority than the current running thread
then yield the CPU to the unblocked thread */
if (!intr_context() && t != NULL && t->priority > thread_get_priority ())
thread_yield ();
} }
static void sema_test_helper (void *sema_); static void sema_test_helper (void *sema_);
@@ -245,6 +233,7 @@ lock_release (struct lock *lock)
lock->holder = NULL; lock->holder = NULL;
sema_up (&lock->semaphore); sema_up (&lock->semaphore);
thread_yield ();
} }
/* Returns true if the current thread holds LOCK, false /* Returns true if the current thread holds LOCK, false
@@ -265,54 +254,6 @@ struct semaphore_elem
struct semaphore semaphore; /* This semaphore. */ struct semaphore semaphore; /* This semaphore. */
}; };
/* Function that compares the two *semaphores* associated with the provided
list_elem structures. [i.e., takes list_elem of semaphore_elem, and]
Returns true if the thread associated with the semaphore associated with a_
has a higher priority than that of b_.
If aux is provided, then it is a pointer to an integer representing the
priority of the first semaphore. This is useful when the thread has not been
sema'd down yet. */
static bool
sema_priority_more(const struct list_elem *a_, const struct list_elem *b_,
void *aux)
{
int a_priority, b_priority;
/* If an aux is provided, then use it as the priority of the first semaphore.
Otherwise, get the priority of the first semaphore. */
if (aux != NULL)
a_priority = *(int *) aux;
else
{
struct semaphore_elem *a = list_entry(a_, struct semaphore_elem, elem);
/* If waiters list is empty, return false (i.e., a has lower priority) */
if (list_empty(&a->semaphore.waiters))
return false;
/* Otherwise, get the thread with the highest priority from the waiters
list. By design, this is the first one in the list (See sema_down). */
struct thread *a_thread =
list_entry(list_front(&a->semaphore.waiters), struct thread, elem);
a_priority = a_thread->priority;
}
struct semaphore_elem *b = list_entry(b_, struct semaphore_elem, elem);
/* If waiters list is empty, return true (i.e., a has higher priority) */
if (list_empty(&b->semaphore.waiters))
return true;
struct thread *b_thread =
list_entry(list_front(&b->semaphore.waiters), struct thread, elem);
b_priority = b_thread->priority;
return a_priority > b_priority;
}
/* Initializes condition variable COND. A condition variable /* Initializes condition variable COND. A condition variable
allows one piece of code to signal a condition and cooperating allows one piece of code to signal a condition and cooperating
code to receive the signal and act upon it. */ code to receive the signal and act upon it. */
@@ -355,14 +296,7 @@ cond_wait (struct condition *cond, struct lock *lock)
ASSERT (lock_held_by_current_thread (lock)); ASSERT (lock_held_by_current_thread (lock));
sema_init (&waiter.semaphore, 0); sema_init (&waiter.semaphore, 0);
list_push_back (&cond->waiters, &waiter.elem);
/* Insert the semaphore_elem into the waiters list in order of priority.
We pass the priority of the current thread as aux to sema_priority_more
because the thread has not been sema'd down yet (See sema_priority_more) */
int priority = thread_current ()->priority;
list_insert_ordered (&cond->waiters, &waiter.elem, sema_priority_more,
&priority);
lock_release (lock); lock_release (lock);
sema_down (&waiter.semaphore); sema_down (&waiter.semaphore);
lock_acquire (lock); lock_acquire (lock);

View File

@@ -4,6 +4,8 @@
#include <random.h> #include <random.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "devices/timer.h"
#include "threads/fixed-point.h"
#include "threads/flags.h" #include "threads/flags.h"
#include "threads/interrupt.h" #include "threads/interrupt.h"
#include "threads/intr-stubs.h" #include "threads/intr-stubs.h"
@@ -49,6 +51,7 @@ struct kernel_thread_frame
static long long idle_ticks; /* # of timer ticks spent idle. */ static long long idle_ticks; /* # of timer ticks spent idle. */
static long long kernel_ticks; /* # of timer ticks in kernel threads. */ static long long kernel_ticks; /* # of timer ticks in kernel threads. */
static long long user_ticks; /* # of timer ticks in user programs. */ static long long user_ticks; /* # of timer ticks in user programs. */
static fp32_t load_avg = { 0 }; /* System load average. */
/* Scheduling. */ /* Scheduling. */
#define TIME_SLICE 4 /* # of timer ticks to give each thread. */ #define TIME_SLICE 4 /* # of timer ticks to give each thread. */
@@ -64,9 +67,14 @@ static void kernel_thread (thread_func *, void *aux);
static void idle (void *aux UNUSED); static void idle (void *aux UNUSED);
static struct thread *running_thread (void); static struct thread *running_thread (void);
static struct thread *next_thread_to_run (void); static struct thread *next_thread_to_run (void);
static void init_thread (struct thread *, const char *name, int priority); static void init_thread (struct thread *, const char *name, int nice,
int priority, fp32_t recent_cpu);
static bool is_thread (struct thread *) UNUSED; static bool is_thread (struct thread *) UNUSED;
static void *alloc_frame (struct thread *, size_t size); static void *alloc_frame (struct thread *, size_t size);
static int calculate_bsd_priority (fp32_t recent_cpu, int nice);
static void thread_update_recent_cpu (struct thread *t, void *aux UNUSED);
static bool thread_priority_less (const struct list_elem *a,
const struct list_elem *b, void *aux UNUSED);
static void schedule (void); static void schedule (void);
void thread_schedule_tail (struct thread *prev); void thread_schedule_tail (struct thread *prev);
static tid_t allocate_tid (void); static tid_t allocate_tid (void);
@@ -95,7 +103,9 @@ thread_init (void)
/* Set up a thread structure for the running thread. */ /* Set up a thread structure for the running thread. */
initial_thread = running_thread (); initial_thread = running_thread ();
init_thread (initial_thread, "main", PRI_DEFAULT); fp32_t initial_thread_recent_cpu = { 0 };
init_thread (initial_thread, "main", NICE_DEFAULT, PRI_DEFAULT,
initial_thread_recent_cpu);
initial_thread->status = THREAD_RUNNING; initial_thread->status = THREAD_RUNNING;
initial_thread->tid = allocate_tid (); initial_thread->tid = allocate_tid ();
} }
@@ -145,6 +155,28 @@ thread_tick (void)
else else
kernel_ticks++; kernel_ticks++;
/* Update system load_avg and all threads recent_cpu every second. */
int64_t ticks = timer_ticks ();
if (thread_mlfqs && (ticks % TIMER_FREQ == 0))
{
size_t ready = threads_ready ();
if (t != idle_thread)
ready++;
fp32_t old_coeff = fp_mul (fp_div_int (int_to_fp (59), 60), load_avg);
fp32_t new_coeff = fp_div_int (int_to_fp (ready), 60);
load_avg = fp_add (old_coeff, new_coeff);
thread_foreach (thread_update_recent_cpu, NULL);
}
/* Update current thread's recent_cpu. */
if (thread_mlfqs && (t != idle_thread))
{
t->recent_cpu = fp_add_int (t->recent_cpu, 1);
if (ticks % 4 == 0) // recent_cpu was updated, update priority.
t->priority = calculate_bsd_priority (t->recent_cpu, t->nice);
}
/* Enforce preemption. */ /* Enforce preemption. */
if (++thread_ticks >= TIME_SLICE) if (++thread_ticks >= TIME_SLICE)
intr_yield_on_return (); intr_yield_on_return ();
@@ -192,7 +224,8 @@ thread_create (const char *name, int priority,
return TID_ERROR; return TID_ERROR;
/* Initialize thread. */ /* Initialize thread. */
init_thread (t, name, priority); struct thread *pt = thread_current ();
init_thread (t, name, pt->nice, priority, pt->recent_cpu);
tid = t->tid = allocate_tid (); tid = t->tid = allocate_tid ();
/* Prepare thread for first run by initializing its stack. /* Prepare thread for first run by initializing its stack.
@@ -220,10 +253,6 @@ thread_create (const char *name, int priority,
/* Add to run queue. */ /* Add to run queue. */
thread_unblock (t); thread_unblock (t);
/* Yield if the new thread has a higher priority than the current thread. */
if (priority > thread_get_priority ())
thread_yield ();
return tid; return tid;
} }
@@ -260,10 +289,10 @@ thread_unblock (struct thread *t)
old_level = intr_disable (); old_level = intr_disable ();
ASSERT (t->status == THREAD_BLOCKED); ASSERT (t->status == THREAD_BLOCKED);
if (thread_mlfqs)
/* Insert the thread back into the ready list in priority order. */ list_insert_ordered (&ready_list, &t->elem, thread_priority_less, NULL);
list_insert_ordered(&ready_list, &t->elem, priority_more, NULL); else
list_push_back (&ready_list, &t->elem);
t->status = THREAD_READY; t->status = THREAD_READY;
intr_set_level (old_level); intr_set_level (old_level);
} }
@@ -333,11 +362,14 @@ thread_yield (void)
ASSERT (!intr_context ()); ASSERT (!intr_context ());
old_level = intr_disable (); old_level = intr_disable ();
if (cur != idle_thread)
/* Insert the thread back into the ready list in priority order. */ {
if (cur != idle_thread) if (thread_mlfqs)
list_insert_ordered(&ready_list, &cur->elem, priority_more, NULL); list_insert_ordered (&ready_list, &cur->elem, thread_priority_less,
NULL);
else
list_push_back (&ready_list, &cur->elem);
}
cur->status = THREAD_READY; cur->status = THREAD_READY;
schedule (); schedule ();
intr_set_level (old_level); intr_set_level (old_level);
@@ -360,57 +392,13 @@ thread_foreach (thread_action_func *func, void *aux)
} }
} }
/* Function that compares the two threads associated with the provided
list_elem structures. Returns true if the thread associated with a_ has
a higher priority than that of b_. */
bool
priority_more (const struct list_elem *a_, const struct list_elem *b_,
void *aux UNUSED)
{
struct thread *a = list_entry (a_, struct thread, elem);
struct thread *b = list_entry (b_, struct thread, elem);
return a->priority > b->priority;
}
/* Sets the current thread's priority to NEW_PRIORITY. */ /* Sets the current thread's priority to NEW_PRIORITY. */
void void
thread_set_priority (int new_priority) thread_set_priority (int new_priority)
{ {
ASSERT (new_priority >= PRI_MIN); if (thread_mlfqs)
ASSERT (new_priority <= PRI_MAX);
int old_priority = thread_get_priority ();
if (new_priority == old_priority)
return; return;
thread_current ()->priority = new_priority; thread_current ()->priority = new_priority;
enum intr_level old_level = intr_disable ();
/* If the thread is in the ready list, the list must be reordered to maintain
the priority order. */
if (thread_current ()->status == THREAD_READY) {
/* Remove from the ready list and reinsert it in priority order. */
list_remove (&thread_current ()->elem);
list_insert_ordered (&ready_list, &thread_current ()->elem, priority_more,
NULL);
}
if (new_priority < old_priority && !list_empty (&ready_list)) {
/* If the new priority is lower than the old priority, check if the current
thread no longer has the highest priority. If it doesn't, yield the CPU.
*/
struct thread *next_thread =
list_entry (list_front (&ready_list), struct thread, elem);
if (next_thread->priority > new_priority) {
thread_yield();
}
}
intr_set_level (old_level);
} }
/* Returns the current thread's priority. */ /* Returns the current thread's priority. */
@@ -420,35 +408,54 @@ thread_get_priority (void)
return thread_current ()->priority; return thread_current ()->priority;
} }
/* Updates recent_cpu for a thread. */
static void
thread_update_recent_cpu (struct thread *t, void *aux UNUSED)
{
fp32_t curr_recent_cpu = t->recent_cpu;
fp32_t dbl_load_avg = fp_mul_int (load_avg, 2);
fp32_t recent_cpu_coeff
= fp_div (dbl_load_avg, fp_add_int (dbl_load_avg, 1));
t->recent_cpu
= fp_add_int (fp_mul (recent_cpu_coeff, curr_recent_cpu), t->nice);
// recent_cpu was updated, update priority.
t->priority = calculate_bsd_priority (t->recent_cpu, t->nice);
}
/* Sets the current thread's nice value to NICE. */ /* Sets the current thread's nice value to NICE. */
void void
thread_set_nice (int nice UNUSED) thread_set_nice (int nice)
{ {
/* Not yet implemented. */ ASSERT (NICE_MIN <= nice && nice <= NICE_MAX);
struct thread *t = thread_current ();
t->nice = nice;
int priority = calculate_bsd_priority (t->recent_cpu, t->nice);
struct thread *next_t
= list_entry (list_begin (&ready_list), struct thread, elem);
if (priority < next_t->priority)
thread_yield ();
} }
/* Returns the current thread's nice value. */ /* Returns the current thread's nice value. */
int int
thread_get_nice (void) thread_get_nice (void)
{ {
/* Not yet implemented. */ return thread_current ()->nice;
return 0;
} }
/* Returns 100 times the system load average. */ /* Returns 100 times the system load average. */
int int
thread_get_load_avg (void) thread_get_load_avg (void)
{ {
/* Not yet implemented. */ return fp_round (fp_mul_int (load_avg, 100));
return 0;
} }
/* Returns 100 times the current thread's recent_cpu value. */ /* Returns 100 times the current thread's recent_cpu value. */
int int
thread_get_recent_cpu (void) thread_get_recent_cpu (void)
{ {
/* Not yet implemented. */ return fp_round (fp_mul_int (thread_current ()->recent_cpu, 100));
return 0;
} }
/* Idle thread. Executes when no other thread is ready to run. /* Idle thread. Executes when no other thread is ready to run.
@@ -524,7 +531,8 @@ is_thread (struct thread *t)
/* Does basic initialization of T as a blocked thread named /* Does basic initialization of T as a blocked thread named
NAME. */ NAME. */
static void static void
init_thread (struct thread *t, const char *name, int priority) init_thread (struct thread *t, const char *name, int nice, int priority,
fp32_t recent_cpu)
{ {
enum intr_level old_level; enum intr_level old_level;
@@ -536,7 +544,10 @@ init_thread (struct thread *t, const char *name, int priority)
t->status = THREAD_BLOCKED; t->status = THREAD_BLOCKED;
strlcpy (t->name, name, sizeof t->name); strlcpy (t->name, name, sizeof t->name);
t->stack = (uint8_t *) t + PGSIZE; t->stack = (uint8_t *) t + PGSIZE;
t->priority = priority; t->priority
= thread_mlfqs ? calculate_bsd_priority (recent_cpu, nice) : priority;
t->nice = nice;
t->recent_cpu = recent_cpu;
t->magic = THREAD_MAGIC; t->magic = THREAD_MAGIC;
old_level = intr_disable (); old_level = intr_disable ();
@@ -617,8 +628,30 @@ thread_schedule_tail (struct thread *prev)
} }
} }
/* Schedules a new process. At entry, interrupts must be off and /* Calculates BSD priority for a thread */
the running process's state must have been changed from static int
calculate_bsd_priority (fp32_t recent_cpu, int nice)
{
int priority = PRI_MAX - (fp_round (recent_cpu) / 4) - (nice * 2);
if (priority < PRI_MIN)
return PRI_MIN;
if (priority > PRI_MAX)
return PRI_MAX;
return priority;
}
/* Returns true if thread a's priority is strictly greater than
thread b's priority. */
static bool
thread_priority_less (const struct list_elem *a, const struct list_elem *b,
void *aux UNUSED)
{
struct thread *ta = list_entry (a, struct thread, elem);
struct thread *tb = list_entry (b, struct thread, elem);
return ta->priority > tb->priority;
}
/* ss's state must have been changed from
running to some other state. This function finds another running to some other state. This function finds another
thread to run and switches to it. thread to run and switches to it.

View File

@@ -4,6 +4,7 @@
#include <debug.h> #include <debug.h>
#include <list.h> #include <list.h>
#include <stdint.h> #include <stdint.h>
#include "threads/fixed-point.h"
/* States in a thread's life cycle. */ /* States in a thread's life cycle. */
enum thread_status enum thread_status
@@ -24,6 +25,10 @@ typedef int tid_t;
#define PRI_DEFAULT 31 /* Default priority. */ #define PRI_DEFAULT 31 /* Default priority. */
#define PRI_MAX 63 /* Highest priority. */ #define PRI_MAX 63 /* Highest priority. */
#define NICE_MIN -20 /* Lowest niceness. */
#define NICE_DEFAULT 0 /* Default niceness. */
#define NICE_MAX 20 /* Highest niceness. */
/* A kernel thread or user process. /* A kernel thread or user process.
Each thread structure is stored in its own 4 kB page. The Each thread structure is stored in its own 4 kB page. The
@@ -93,6 +98,10 @@ struct thread
/* Shared between thread.c and synch.c. */ /* Shared between thread.c and synch.c. */
struct list_elem elem; /* List element. */ struct list_elem elem; /* List element. */
/* MLFQS items */
int nice; /* Nice value for this thread */
fp32_t recent_cpu; /* Amount of time this process received */
#ifdef USERPROG #ifdef USERPROG
/* Owned by userprog/process.c. */ /* Owned by userprog/process.c. */
uint32_t *pagedir; /* Page directory. */ uint32_t *pagedir; /* Page directory. */
@@ -131,8 +140,6 @@ void thread_yield (void);
typedef void thread_action_func (struct thread *t, void *aux); typedef void thread_action_func (struct thread *t, void *aux);
void thread_foreach (thread_action_func *, void *); void thread_foreach (thread_action_func *, void *);
bool priority_more (const struct list_elem *a_, const struct list_elem *b_,
void *aux UNUSED);
int thread_get_priority (void); int thread_get_priority (void);
void thread_set_priority (int); void thread_set_priority (int);