Cleanup.
This commit is contained in:
		@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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]);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user