This commit is contained in:
Geoffrey Challen 2016-02-11 19:53:53 -05:00
parent db6d3d219d
commit 4b630a915d
3 changed files with 72 additions and 124 deletions

View File

@ -30,4 +30,4 @@ options sfs # Always use the file system
#options netfs # You might write this as a project. #options netfs # You might write this as a project.
options dumbvm # Chewing gum and baling wire. options dumbvm # Chewing gum and baling wire.
#options synchprobs # Uncomment to enable ASST1 synchronization problems options synchprobs # Uncomment to enable ASST1 synchronization problems

View File

@ -32,16 +32,25 @@ struct spinlock status_lock;
static bool test_status = FAIL; static bool test_status = FAIL;
const char *test_message; const char *test_message;
static
bool
failif(bool condition, const char *message) {
if (condition) {
spinlock_acquire(&status_lock);
test_status = FAIL;
test_message = message;
spinlock_release(&status_lock);
}
return condition;
}
/* /*
* Helper function to initialize the thread pool. * Helper function to initialize the thread pool.
*/ */
static static
void void
initialize_thread(volatile void* threads[], uint32_t index) { initialize_thread(volatile void* threads[], uint32_t index) {
if (threads[index] != NULL) { failif((threads[index] != NULL), "failed: incorrect thread type");
test_status = FAIL;
test_message = "failed: incorrect thread type";
}
threads[index] = curthread->t_stack; threads[index] = curthread->t_stack;
} }
@ -51,10 +60,7 @@ initialize_thread(volatile void* threads[], uint32_t index) {
static static
void void
check_thread(volatile void* threads[], uint32_t index) { check_thread(volatile void* threads[], uint32_t index) {
if (threads[index] != curthread->t_stack) { failif((threads[index] != curthread->t_stack), "failed: incorrect thread type");
test_status = FAIL;
test_message = "failed: incorrect thread type";
}
} }
/* /*
@ -87,10 +93,7 @@ static struct semaphore *matcher_sem;
static static
void void
check_role(uint32_t index, int role) { check_role(uint32_t index, int role) {
if (whale_roles[index] != role) { failif((whale_roles[index] != role), "failed: incorrect role");
test_status = FAIL;
test_message = "failed: incorrect role";
}
} }
static static
@ -232,12 +235,8 @@ matchmaker_end(uint32_t index) {
static static
void void
check_zero(int count, const char *name) { check_zero(int count) {
(void)name; failif((count != 0), "failed: not all threads completed");
if (count != 0) {
test_status = FAIL;
test_message = "failed: not all threads completed";
}
} }
int int
@ -321,9 +320,7 @@ whalemating(int nargs, char **args) {
} }
lock_release(testlock); lock_release(testlock);
} }
if (loop_status == FAIL) { if (failif((loop_status == FAIL), "failed: uncoordinated matchmaking is occurring")) {
test_status = FAIL;
test_message = "failed: uncoordinated matchmaking is occurring";
goto done; goto done;
} }
@ -368,9 +365,7 @@ whalemating(int nargs, char **args) {
} }
lock_release(testlock); lock_release(testlock);
} }
if (loop_status == FAIL) { if (failif((loop_status == FAIL), "failed: uncoordinated matchmaking is occurring")) {
test_status = FAIL;
test_message = "failed: uncoordinating matchmaking is occurring";
goto done; goto done;
} }
@ -392,12 +387,12 @@ whalemating(int nargs, char **args) {
whalemating_cleanup(); whalemating_cleanup();
check_zero(male_start_count - NMATING, "male"); check_zero(male_start_count - NMATING);
check_zero(female_start_count - NMATING, "female"); check_zero(female_start_count - NMATING);
check_zero(matchmaker_start_count - NMATING, "matchmaker"); check_zero(matchmaker_start_count - NMATING);
check_zero(male_start_count - male_end_count, "male"); check_zero(male_start_count - male_end_count);
check_zero(female_start_count - female_end_count, "female"); check_zero(female_start_count - female_end_count);
check_zero(matchmaker_start_count - matchmaker_end_count, "matchmaker"); check_zero(matchmaker_start_count - matchmaker_end_count);
if (match_count == NMATING) { if (match_count == NMATING) {
for (i = 0; i < NMATING; i++) { for (i = 0; i < NMATING; i++) {
@ -405,18 +400,10 @@ whalemating(int nargs, char **args) {
j = i * 3; j = i * 3;
int male = match_status[j]; int male = match_status[j];
int female = match_status[j + 1]; int female = match_status[j + 1];
if (male == 0 || female == 0) { failif((male == 0 || female == 0), "failed: not all males were matched");
spinlock_acquire(&status_lock);
test_status = FAIL;
test_message = "failed: not all males were matched";
spinlock_release(&status_lock);
}
} }
} else { } else {
spinlock_acquire(&status_lock); failif(true, "failed: not all males were matched");
test_status = FAIL;
test_message = "failed: not all males were matched";
spinlock_release(&status_lock);
} }
done: done:
@ -474,10 +461,7 @@ void
check_intersection() { check_intersection() {
int n = 0; int n = 0;
for (int i = 0; i < NUM_QUADRANTS; i++) { for (int i = 0; i < NUM_QUADRANTS; i++) {
if (quadrant_array[i] > 1) { failif((quadrant_array[i] > 1), "failed: collision");
test_message = "failed: collision";
test_status = FAIL;
}
n += quadrant_array[i]; n += quadrant_array[i];
} }
max_car_count = n > max_car_count ? n : max_car_count; max_car_count = n > max_car_count ? n : max_car_count;
@ -569,39 +553,26 @@ inQuadrant(int quadrant, uint32_t index) {
int target_quadrant = car_directions[index]; int target_quadrant = car_directions[index];
switch (car_turn_times[index]) { switch (car_turn_times[index]) {
case 0: case 0:
if (pre_quadrant != UNKNOWN_CAR) { failif((pre_quadrant != UNKNOWN_CAR), "failed: invalid turn");
test_message = "failed: invalid turn";
test_status = FAIL;
}
break; break;
case 1: case 1:
if (pre_quadrant != target_quadrant) { failif((pre_quadrant != target_quadrant), "failed: invalid turn");
test_message = "failed: invalid turn";
test_status = FAIL;
}
target_quadrant = (target_quadrant + NUM_QUADRANTS - 1) % NUM_QUADRANTS; target_quadrant = (target_quadrant + NUM_QUADRANTS - 1) % NUM_QUADRANTS;
break; break;
case 2: case 2:
target_quadrant = (target_quadrant + NUM_QUADRANTS - 1) % NUM_QUADRANTS; target_quadrant = (target_quadrant + NUM_QUADRANTS - 1) % NUM_QUADRANTS;
if (pre_quadrant != target_quadrant) { failif((pre_quadrant != target_quadrant), "failed: invalid turn");
test_message = "failed: invalid turn";
test_status = FAIL;
}
target_quadrant = (target_quadrant + NUM_QUADRANTS - 1) % NUM_QUADRANTS; target_quadrant = (target_quadrant + NUM_QUADRANTS - 1) % NUM_QUADRANTS;
break; break;
default: default:
test_status = FAIL; failif(true, "failed: invalid turn");
break; break;
} }
if (quadrant != target_quadrant) { failif((quadrant != target_quadrant), "failed: invalid turn");
test_status = FAIL;
}
car_turn_times[index]++; car_turn_times[index]++;
if (quadrant_array[quadrant] > 0) { failif((quadrant_array[quadrant] > 0), "failed: collision");
test_message = "failed: collision";
test_status = FAIL;
}
quadrant_array[quadrant]++; quadrant_array[quadrant]++;
car_locations[index] = quadrant; car_locations[index] = quadrant;
all_quadrant++; all_quadrant++;
@ -619,25 +590,16 @@ leaveIntersection(uint32_t index) {
switch (car_turns[index]) { switch (car_turns[index]) {
case GO_STRAIGHT: case GO_STRAIGHT:
if (car_turn_times[index] != 2) { failif((car_turn_times[index] != 2), "failed: incorrect turn");
test_message = "failed: incorrect turn";
test_status = FAIL;
}
break; break;
case TURN_LEFT: case TURN_LEFT:
if (car_turn_times[index] != 3) { failif((car_turn_times[index] != 3), "failed: incorrect turn");
test_message = "failed: incorrect turn";
test_status = FAIL;
}
break; break;
case TURN_RIGHT: case TURN_RIGHT:
if (car_turn_times[index] != 1) { failif((car_turn_times[index] != 1), "failed: incorrect turn");
test_message = "failed: incorrect turn";
test_status = FAIL;
}
break; break;
default: default:
test_status = FAIL; failif(true, "failed: incorrect turn");
break; break;
} }
@ -722,18 +684,10 @@ int stoplight(int nargs, char **args) {
for (i = 0; i < NCARS; i++) { for (i = 0; i < NCARS; i++) {
passed += car_locations[i] == PASSED_CAR ? 1 : 0; passed += car_locations[i] == PASSED_CAR ? 1 : 0;
} }
if (test_status == SUCCESS) { if ((test_status == SUCCESS) &&
if (passed != NCARS) { (!failif((passed != NCARS), "failed: not enough cars")) &&
test_message = "failed: not enough cars"; (!(failif((all_quadrant != required_quadrant), "failed: didn't do the right turns"))) &&
test_status = FAIL; (!(failif((max_car_count <= 1), "failed: no concurrency achieved")))) {};
} else if (all_quadrant != required_quadrant) {
test_message = "failed: didn't do the right turns";
test_status = FAIL;
} else if (max_car_count <= 1) {
test_message = "failed: no concurrency achieved";
test_status = FAIL;
}
}
lock_destroy(testlock); lock_destroy(testlock);
cv_destroy(startcv); cv_destroy(startcv);

View File

@ -65,6 +65,17 @@ static bool test_status = FAIL;
static unsigned long semtest_current; static unsigned long semtest_current;
static
bool
failif(bool condition) {
if (condition) {
spinlock_acquire(&status_lock);
test_status = FAIL;
spinlock_release(&status_lock);
}
return condition;
}
static static
void void
semtestthread(void *junk, unsigned long num) semtestthread(void *junk, unsigned long num)
@ -86,11 +97,7 @@ semtestthread(void *junk, unsigned long num)
kprintf_t("."); kprintf_t(".");
kprintf_n("%2lu", num); kprintf_n("%2lu", num);
random_yielder(4); random_yielder(4);
if (semtest_current != num) { failif((semtest_current != num));
spinlock_acquire(&status_lock);
test_status = FAIL;
spinlock_release(&status_lock);
}
} }
kprintf_n("\n"); kprintf_n("\n");
@ -224,9 +231,7 @@ locktestthread(void *junk, unsigned long num)
fail: fail:
lock_release(testlock); lock_release(testlock);
fail2: fail2:
spinlock_acquire(&status_lock); failif(true);
test_status = FAIL;
spinlock_release(&status_lock);
V(donesem); V(donesem);
return; return;
} }
@ -373,10 +378,8 @@ cvtestthread(void *junk, unsigned long num)
/* Require at least 2000 cpu cycles (we're 25mhz) */ /* Require at least 2000 cpu cycles (we're 25mhz) */
if (ts2.tv_sec == 0 && ts2.tv_nsec < 40*2000) { if (ts2.tv_sec == 0 && ts2.tv_nsec < 40*2000) {
kprintf_n("cv_wait took only %u ns\n", ts2.tv_nsec); kprintf_n("cv_wait took only %u ns\n", ts2.tv_nsec);
kprintf_n("That's too fast... you must be " "busy-looping\n"); kprintf_n("That's too fast... you must be busy-looping\n");
spinlock_acquire(&status_lock); failif(true);
test_status = FAIL;
spinlock_release(&status_lock);
V(donesem); V(donesem);
thread_exit(); thread_exit();
} }
@ -394,12 +397,7 @@ cvtestthread(void *junk, unsigned long num)
random_yielder(4); random_yielder(4);
cv_broadcast(testcv, testlock); cv_broadcast(testcv, testlock);
random_yielder(4); random_yielder(4);
failif((testval1 != testval2));
spinlock_acquire(&status_lock);
if (testval1 != testval2) {
test_status = FAIL;
}
spinlock_release(&status_lock);
kprintf_n("Thread %lu\n", testval2); kprintf_n("Thread %lu\n", testval2);
testval1 = (testval1 + NTHREADS - 1) % NTHREADS; testval1 = (testval1 + NTHREADS - 1) % NTHREADS;
@ -532,12 +530,8 @@ wakethread(void *junk1, unsigned long junk2)
random_yielder(4); random_yielder(4);
lock_acquire(testlocks[i]); lock_acquire(testlocks[i]);
random_yielder(4); random_yielder(4);
spinlock_acquire(&status_lock);
testval4--; testval4--;
if (testval4 != 0) { failif((testval4 != 0));
test_status = FAIL;
}
spinlock_release(&status_lock);
cv_signal(testcvs[i], testlocks[i]); cv_signal(testcvs[i], testlocks[i]);
random_yielder(4); random_yielder(4);
lock_release(testlocks[i]); lock_release(testlocks[i]);