From 4b9c6406e80d1fe9e5aa236e0d34dadbc4703307 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Thu, 18 May 2006 17:08:41 +0000 Subject: [PATCH] Add test that checks that recent_cpu decays properly for blocked threads. Suggested by Godmar Back. --- TODO | 16 -------- src/tests/threads/Make.tests | 6 ++- src/tests/threads/Rubric.mlfqs | 2 + src/tests/threads/mlfqs-block.c | 64 ++++++++++++++++++++++++++++++++ src/tests/threads/mlfqs-block.ck | 16 ++++++++ src/tests/threads/tests.c | 1 + src/tests/threads/tests.h | 1 + 7 files changed, 88 insertions(+), 18 deletions(-) create mode 100644 src/tests/threads/mlfqs-block.c create mode 100644 src/tests/threads/mlfqs-block.ck diff --git a/TODO b/TODO index 737f9af..a4e3e31 100644 --- a/TODO +++ b/TODO @@ -26,22 +26,6 @@ Add a system call "get_kernel_memory_information". User programs could engage in a variety of activities and notice leaks by checking the kernel memory statistics. -From: "Godmar Back" - -For reasons I don't currently understand, some of our students seem -hesitant to include each thread in a second "all-threads" list and are -looking for ways to implement the advanced scheduler without one. - -Currently, I believe, all tests for the mlfqs are such that all -threads are either ready or sleeping in timer_sleep(). This allows for -an incorrect implementation in which recent-cpu and priorities are -updated only for those threads that are on the alarm list or the ready -list. - -The todo item would be a test where a thread is blocked on a -semaphore, lock or condition variable and have its recent_cpu decay to -zero, and check that it's scheduled right after the unlock/up/signal. - From: "Godmar Back" Subject: set_priority & donation - a TODO item To: "Ben Pfaff" diff --git a/src/tests/threads/Make.tests b/src/tests/threads/Make.tests index 0b6d532..3b6bfd7 100644 --- a/src/tests/threads/Make.tests +++ b/src/tests/threads/Make.tests @@ -8,7 +8,7 @@ priority-donate-multiple priority-donate-multiple2 \ priority-donate-nest priority-donate-sema priority-fifo \ priority-preempt priority-sema priority-condvar mlfqs-load-1 \ mlfqs-load-60 mlfqs-load-avg mlfqs-recent-1 mlfqs-fair-2 mlfqs-fair-20 \ -mlfqs-nice-2 mlfqs-nice-10) +mlfqs-nice-2 mlfqs-nice-10 mlfqs-block) # Sources for tests. tests/threads_SRC = tests/threads/tests.c @@ -32,6 +32,7 @@ tests/threads_SRC += tests/threads/mlfqs-load-60.c tests/threads_SRC += tests/threads/mlfqs-load-avg.c tests/threads_SRC += tests/threads/mlfqs-recent-1.c tests/threads_SRC += tests/threads/mlfqs-fair.c +tests/threads_SRC += tests/threads/mlfqs-block.c MLFQS_OUTPUTS = \ tests/threads/mlfqs-load-1.output \ @@ -41,7 +42,8 @@ tests/threads/mlfqs-recent-1.output \ tests/threads/mlfqs-fair-2.output \ tests/threads/mlfqs-fair-20.output \ tests/threads/mlfqs-nice-2.output \ -tests/threads/mlfqs-nice-10.output +tests/threads/mlfqs-nice-10.output \ +tests/threads/mlfqs-block.output $(MLFQS_OUTPUTS): KERNELFLAGS += -mlfqs $(MLFQS_OUTPUTS): TIMEOUT = 240 diff --git a/src/tests/threads/Rubric.mlfqs b/src/tests/threads/Rubric.mlfqs index b238a57..f260091 100644 --- a/src/tests/threads/Rubric.mlfqs +++ b/src/tests/threads/Rubric.mlfqs @@ -10,3 +10,5 @@ Functionality of advanced scheduler: 4 mlfqs-nice-2 2 mlfqs-nice-10 + +5 mlfqs-block diff --git a/src/tests/threads/mlfqs-block.c b/src/tests/threads/mlfqs-block.c new file mode 100644 index 0000000..93ed5ec --- /dev/null +++ b/src/tests/threads/mlfqs-block.c @@ -0,0 +1,64 @@ +/* Checks that recent_cpu and priorities are updated for blocked + threads. + + The main thread sleeps for 25 seconds, spins for 5 seconds, + then releases a lock. The "block" thread spins for 20 seconds + then attempts to acquire the lock, which will block for 10 + seconds (until the main thread releases it). If recent_cpu + decays properly while the "block" thread sleeps, then the + block thread should be immediately scheduled when the main + thread releases the lock,. */ + +#include +#include "tests/threads/tests.h" +#include "threads/init.h" +#include "threads/malloc.h" +#include "threads/synch.h" +#include "threads/thread.h" +#include "devices/timer.h" + +static void block_thread (void *lock_); + +void +test_mlfqs_block (void) +{ + int64_t start_time; + struct lock lock; + + ASSERT (enable_mlfqs); + + msg ("Main thread acquiring lock."); + lock_init (&lock); + lock_acquire (&lock); + + msg ("Main thread creating block thread, sleeping 25 seconds..."); + thread_create ("block", PRI_DEFAULT, block_thread, &lock); + timer_sleep (25 * TIMER_FREQ); + + msg ("Main thread spinning for 5 seconds..."); + start_time = timer_ticks (); + while (timer_elapsed (start_time) < 5 * TIMER_FREQ) + continue; + + msg ("Main thread releasing lock."); + lock_release (&lock); + + msg ("Block thread should have already acquired lock."); +} + +static void +block_thread (void *lock_) +{ + struct lock *lock = lock_; + int64_t start_time; + + msg ("Block thread spinning for 20 seconds..."); + start_time = timer_ticks (); + while (timer_elapsed (start_time) < 20 * TIMER_FREQ) + continue; + + msg ("Block thread acquiring lock..."); + lock_acquire (lock); + + msg ("...got it."); +} diff --git a/src/tests/threads/mlfqs-block.ck b/src/tests/threads/mlfqs-block.ck new file mode 100644 index 0000000..e3b883a --- /dev/null +++ b/src/tests/threads/mlfqs-block.ck @@ -0,0 +1,16 @@ +# -*- perl -*- +use strict; +use warnings; +use tests::tests; +check_expected ([<<'EOF']); +(mlfqs-block) begin +(mlfqs-block) Main thread acquiring lock. +(mlfqs-block) Main thread creating block thread, sleeping 25 seconds... +(mlfqs-block) Block thread spinning for 20 seconds... +(mlfqs-block) Block thread acquiring lock... +(mlfqs-block) Main thread spinning for 5 seconds... +(mlfqs-block) Main thread releasing lock. +(mlfqs-block) ...got it. +(mlfqs-block) Block thread should have already acquired lock. +(mlfqs-block) end +EOF diff --git a/src/tests/threads/tests.c b/src/tests/threads/tests.c index ca99eb6..b515372 100644 --- a/src/tests/threads/tests.c +++ b/src/tests/threads/tests.c @@ -35,6 +35,7 @@ static const struct test tests[] = {"mlfqs-fair-20", test_mlfqs_fair_20}, {"mlfqs-nice-2", test_mlfqs_nice_2}, {"mlfqs-nice-10", test_mlfqs_nice_10}, + {"mlfqs-block", test_mlfqs_block}, }; static const char *test_name; diff --git a/src/tests/threads/tests.h b/src/tests/threads/tests.h index ed9fbac..1fe839e 100644 --- a/src/tests/threads/tests.h +++ b/src/tests/threads/tests.h @@ -29,6 +29,7 @@ extern test_func test_mlfqs_fair_2; extern test_func test_mlfqs_fair_20; extern test_func test_mlfqs_nice_2; extern test_func test_mlfqs_nice_10; +extern test_func test_mlfqs_block; void msg (const char *, ...); void fail (const char *, ...); -- 2.30.2