Synchronization problem stubs and drivers.
This commit is contained in:
parent
1b63251154
commit
f818d0bd30
@ -438,3 +438,8 @@ file test/semunit.c
|
||||
file test/kmalloctest.c
|
||||
file test/fstest.c
|
||||
optfile net test/nettest.c
|
||||
|
||||
defoption synchprobs
|
||||
optfile synchprobs synchprobs/whalemating.c
|
||||
optfile synchprobs synchprobs/stoplight.c
|
||||
optfile synchprobs test/synchprobs.c
|
||||
|
28
kern/include/synchprobs.h
Normal file
28
kern/include/synchprobs.h
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef _SYNCHPROBS_H_
|
||||
#define _SYNCHPROBS_H_
|
||||
|
||||
/*
|
||||
* Synchronization problem primitives.
|
||||
*/
|
||||
|
||||
/*
|
||||
* whalemating.c.
|
||||
*/
|
||||
|
||||
void whalemating_init(void);
|
||||
void whalemating_cleanup(void);
|
||||
void male(void *, unsigned long);
|
||||
void female(void *, unsigned long);
|
||||
void matchmaker(void *, unsigned long);
|
||||
|
||||
/*
|
||||
* stoplight.c.
|
||||
*/
|
||||
|
||||
void gostraight(void *, unsigned long);
|
||||
void turnleft(void *, unsigned long);
|
||||
void turnright(void *, unsigned long);
|
||||
void stoplight_init(void);
|
||||
void stoplight_cleanup(void);
|
||||
|
||||
#endif /* _SYNCHPROBS_H_ */
|
@ -30,6 +30,8 @@
|
||||
#ifndef _TEST_H_
|
||||
#define _TEST_H_
|
||||
|
||||
#include "opt-synchprobs.h"
|
||||
|
||||
/*
|
||||
* Declarations for test code and other miscellaneous high-level
|
||||
* functions.
|
||||
@ -105,5 +107,24 @@ void menu(char *argstr);
|
||||
/* The main function, called from start.S. */
|
||||
void kmain(char *bootstring);
|
||||
|
||||
#if OPT_SYNCHPROBS
|
||||
|
||||
/*
|
||||
* Synchronization driver primitives.
|
||||
*/
|
||||
|
||||
void male_start(void);
|
||||
void male_end(void);
|
||||
void female_start(void);
|
||||
void female_end(void);
|
||||
void matchmaker_start(void);
|
||||
void matchmaker_end(void);
|
||||
int whalemating(int, char **);
|
||||
|
||||
void inQuadrant(int);
|
||||
void leaveIntersection(void);
|
||||
int stoplight(int, char **);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _TEST_H_ */
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include <prompt.h>
|
||||
#include "opt-sfs.h"
|
||||
#include "opt-net.h"
|
||||
#include "opt-synchprobs.h"
|
||||
|
||||
/*
|
||||
* In-kernel menu and command dispatcher.
|
||||
@ -478,6 +479,10 @@ static const char *testmenu[] = {
|
||||
"[sy3] CV test (1) ",
|
||||
"[sy4] CV test #2 (1) ",
|
||||
"[sy5] RW lock test (1) ",
|
||||
#if OPT_SYNCHPROBS
|
||||
"[sp1] Whalemating test (1) ",
|
||||
"[sp2] Stoplight test (1) ",
|
||||
#endif
|
||||
"[semu1-22] Semaphore unit tests ",
|
||||
"[fs1] Filesystem test ",
|
||||
"[fs2] FS read stress ",
|
||||
@ -581,6 +586,10 @@ static struct {
|
||||
{ "sy3", cvtest },
|
||||
{ "sy4", cvtest2 },
|
||||
{ "sy5", rwtest },
|
||||
#if OPT_SYNCHPROBS
|
||||
{ "sp1", whalemating },
|
||||
{ "sp2", stoplight },
|
||||
#endif
|
||||
|
||||
/* semaphore unit tests */
|
||||
{ "semu1", semu1 },
|
||||
|
133
kern/synchprobs/stoplight.c
Normal file
133
kern/synchprobs/stoplight.c
Normal file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2002, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Driver code is in kern/tests/synchprobs.c We will
|
||||
* replace that file. This file is yours to modify as you see fit.
|
||||
*
|
||||
* You should implement your solution to the stoplight problem below. The
|
||||
* quadrant and direction mappings for reference: (although the problem is,
|
||||
* of course, stable under rotation)
|
||||
*
|
||||
* | 0 |
|
||||
* -- --
|
||||
* 0 1
|
||||
* 3 1
|
||||
* 3 2
|
||||
* -- --
|
||||
* | 2 |
|
||||
*
|
||||
* As way to think about it, assuming cars drive on the right: a car entering
|
||||
* the intersection from direction X will enter intersection quadrant X
|
||||
* first.
|
||||
*
|
||||
* You will probably want to write some helper functions to assist
|
||||
* with the mappings. Modular arithmetic can help, e.g. a car passing
|
||||
* straight through the intersection entering from direction X will leave to
|
||||
* direction (X + 2) % 4 and pass through quadrants X and (X + 3) % 4.
|
||||
* Boo-yah.
|
||||
*
|
||||
* Your solutions below should call the inQuadrant() and leaveIntersection()
|
||||
* functions in synchprobs.c to record their progress.
|
||||
*/
|
||||
|
||||
#include <types.h>
|
||||
#include <lib.h>
|
||||
#include <thread.h>
|
||||
#include <test.h>
|
||||
#include <synch.h>
|
||||
#include <synchprobs.h>
|
||||
|
||||
/*
|
||||
* Called by the driver during initialization.
|
||||
*/
|
||||
|
||||
void
|
||||
stoplight_init() {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called by the driver during teardown.
|
||||
*/
|
||||
|
||||
void stoplight_cleanup() {
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
gostraight(void *p, unsigned long direction)
|
||||
{
|
||||
struct semaphore * stoplightMenuSemaphore = (struct semaphore *)p;
|
||||
(void)direction;
|
||||
|
||||
/*
|
||||
* Implement this function.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code allows the test to return to the menu cleanly.
|
||||
*/
|
||||
V(stoplightMenuSemaphore);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
turnleft(void *p, unsigned long direction)
|
||||
{
|
||||
struct semaphore * stoplightMenuSemaphore = (struct semaphore *)p;
|
||||
(void)direction;
|
||||
|
||||
/*
|
||||
* Implement this function.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code allows the test to return to the menu cleanly.
|
||||
*/
|
||||
V(stoplightMenuSemaphore);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
turnright(void *p, unsigned long direction)
|
||||
{
|
||||
struct semaphore * stoplightMenuSemaphore = (struct semaphore *)p;
|
||||
(void)direction;
|
||||
|
||||
/*
|
||||
* Implement this function.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code allows the test to return to the menu cleanly.
|
||||
*/
|
||||
V(stoplightMenuSemaphore);
|
||||
return;
|
||||
}
|
116
kern/synchprobs/whalemating.c
Normal file
116
kern/synchprobs/whalemating.c
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2002, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Driver code is in kern/tests/synchprobs.c We will
|
||||
* replace that file. This file is yours to modify as you see fit.
|
||||
*
|
||||
* You should implement your solution to the whalemating problem below.
|
||||
*/
|
||||
|
||||
#include <types.h>
|
||||
#include <lib.h>
|
||||
#include <thread.h>
|
||||
#include <test.h>
|
||||
#include <synch.h>
|
||||
#include <synchprobs.h>
|
||||
|
||||
/*
|
||||
* Called by the driver during initialization.
|
||||
*/
|
||||
|
||||
void whalemating_init() {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called by the driver during teardown.
|
||||
*/
|
||||
|
||||
void
|
||||
whalemating_cleanup() {
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
male(void *p, unsigned long which)
|
||||
{
|
||||
struct semaphore * whalematingMenuSemaphore = (struct semaphore *)p;
|
||||
(void)which;
|
||||
|
||||
male_start();
|
||||
/*
|
||||
* Implement this function.
|
||||
*/
|
||||
male_end();
|
||||
|
||||
/*
|
||||
* This code allows the test to return to the menu cleanly.
|
||||
*/
|
||||
V(whalematingMenuSemaphore);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
female(void *p, unsigned long which)
|
||||
{
|
||||
struct semaphore * whalematingMenuSemaphore = (struct semaphore *)p;
|
||||
(void)which;
|
||||
|
||||
female_start();
|
||||
/*
|
||||
* Implement this function.
|
||||
*/
|
||||
female_end();
|
||||
|
||||
/*
|
||||
* This code allows the test to return to the menu cleanly.
|
||||
*/
|
||||
V(whalematingMenuSemaphore);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
matchmaker(void *p, unsigned long which)
|
||||
{
|
||||
struct semaphore * whalematingMenuSemaphore = (struct semaphore *)p;
|
||||
(void)which;
|
||||
|
||||
matchmaker_start();
|
||||
/*
|
||||
* Implement this function.
|
||||
*/
|
||||
matchmaker_end();
|
||||
|
||||
/*
|
||||
* This code allows the test to return to the menu cleanly.
|
||||
*/
|
||||
V(whalematingMenuSemaphore);
|
||||
return;
|
||||
}
|
202
kern/test/synchprobs.c
Normal file
202
kern/test/synchprobs.c
Normal file
@ -0,0 +1,202 @@
|
||||
/*
|
||||
* 08 Feb 2012 : GWA : Please make any changes necessary to test your code to
|
||||
* the drivers in this file. However, the automated testing suite *will
|
||||
* replace this file in its entirety* with driver code intented to stress
|
||||
* test your synchronization problem solutions.
|
||||
*/
|
||||
|
||||
#include <types.h>
|
||||
#include <lib.h>
|
||||
#include <thread.h>
|
||||
#include <test.h>
|
||||
#include <current.h>
|
||||
#include <synch.h>
|
||||
#include <synchprobs.h>
|
||||
|
||||
#define PROBLEMS_MAX_YIELDER 16
|
||||
#define PROBLEMS_MAX_SPINNER 8192
|
||||
|
||||
/*
|
||||
* 08 Feb 2012 : GWA : Driver code for the whalemating problem.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 08 Feb 2012 : GWA : The following functions are for you to use when each
|
||||
* whale starts and completes either mating (if it is a male or female) or
|
||||
* matchmaking. We will use the output from these functions to verify the to
|
||||
* verify the correctness of your solution. These functions may spin for
|
||||
* arbitrary periods of time or yield.
|
||||
*/
|
||||
|
||||
inline void male_start(void) {
|
||||
random_yielder(PROBLEMS_MAX_YIELDER);
|
||||
kprintf("%s starting\n", curthread->t_name);
|
||||
}
|
||||
|
||||
inline void male_end(void) {
|
||||
kprintf("%s ending\n", curthread->t_name);
|
||||
}
|
||||
|
||||
inline void female_start(void) {
|
||||
random_spinner(PROBLEMS_MAX_SPINNER);
|
||||
kprintf("%s starting\n", curthread->t_name);
|
||||
}
|
||||
|
||||
inline void female_end(void) {
|
||||
kprintf("%s ending\n", curthread->t_name);
|
||||
}
|
||||
|
||||
inline void matchmaker_start(void) {
|
||||
random_yielder(PROBLEMS_MAX_YIELDER);
|
||||
kprintf("%s starting\n", curthread->t_name);
|
||||
}
|
||||
|
||||
inline void matchmaker_end(void) {
|
||||
kprintf("%s ending\n", curthread->t_name);
|
||||
}
|
||||
|
||||
/*
|
||||
* 08 Feb 2012 : GWA : The following function drives the entire whalemating
|
||||
* process. Feel free to modify at will, but make no assumptions about the
|
||||
* order or timing of threads launched by our testing suite.
|
||||
*/
|
||||
|
||||
#define NMATING 10
|
||||
|
||||
struct semaphore * whalematingMenuSemaphore;
|
||||
|
||||
int whalemating(int nargs, char **args) {
|
||||
(void) nargs;
|
||||
(void) args;
|
||||
|
||||
int i, j, err = 0;
|
||||
char name[32];
|
||||
|
||||
whalematingMenuSemaphore = sem_create("Whalemating Driver Semaphore",
|
||||
0);
|
||||
if (whalematingMenuSemaphore == NULL ) {
|
||||
panic("whalemating: sem_create failed.\n");
|
||||
}
|
||||
|
||||
whalemating_init();
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < NMATING; j++) {
|
||||
|
||||
random_yielder(PROBLEMS_MAX_YIELDER);
|
||||
|
||||
switch (i) {
|
||||
case 0:
|
||||
snprintf(name, sizeof(name), "Male Whale Thread %d", (i * 3) + j);
|
||||
err = thread_fork(name, NULL, male, whalematingMenuSemaphore, j);
|
||||
break;
|
||||
case 1:
|
||||
snprintf(name, sizeof(name), "Female Whale Thread %d", (i * 3) + j);
|
||||
err = thread_fork(name, NULL, female, whalematingMenuSemaphore, j);
|
||||
break;
|
||||
case 2:
|
||||
snprintf(name, sizeof(name), "Matchmaker Whale Thread %d", (i * 3) + j);
|
||||
err = thread_fork(name, NULL, matchmaker, whalematingMenuSemaphore, j);
|
||||
break;
|
||||
}
|
||||
if (err) {
|
||||
panic("whalemating: thread_fork failed: (%s)\n", strerror(err));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < NMATING; j++) {
|
||||
P(whalematingMenuSemaphore);
|
||||
}
|
||||
}
|
||||
|
||||
sem_destroy(whalematingMenuSemaphore);
|
||||
whalemating_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 08 Feb 2012 : GWA : Driver code for the stoplight problem.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 08 Feb 2012 : GWA : The following functions should be called by your
|
||||
* stoplight solution when a car is in an intersection quadrant. The
|
||||
* semantics of the problem are that once a car enters any quadrant it has to
|
||||
* be somewhere in the intersection until it call leaveIntersection(), which
|
||||
* it should call while in the final quadrant.
|
||||
*
|
||||
* As an example, let's say a car approaches the intersection and needs to
|
||||
* pass through quadrants 0, 3 and 2. Once you call inQuadrant(0), the car is
|
||||
* considered in quadrant 0 until you call inQuadrant(3). After you call
|
||||
* inQuadrant(2), the car is considered in quadrant 2 until you call
|
||||
* leaveIntersection().
|
||||
*
|
||||
* As in the whalemating example, we will use the output from these functions
|
||||
* to verify the correctness of your solution. These functions may spin for
|
||||
* arbitrary periods of time or yield.
|
||||
*/
|
||||
|
||||
inline void inQuadrant(int quadrant) {
|
||||
random_spinner(PROBLEMS_MAX_SPINNER);
|
||||
kprintf("%s in quadrant %d\n", curthread->t_name, quadrant);
|
||||
}
|
||||
|
||||
inline void leaveIntersection() {
|
||||
kprintf("%s left the intersection\n", curthread->t_name);
|
||||
}
|
||||
|
||||
#define NCARS 99
|
||||
|
||||
struct semaphore * stoplightMenuSemaphore;
|
||||
|
||||
int stoplight(int nargs, char **args) {
|
||||
(void) nargs;
|
||||
(void) args;
|
||||
int i, direction, turn, err = 0;
|
||||
char name[32];
|
||||
|
||||
stoplightMenuSemaphore = sem_create("Stoplight Driver Semaphore", 0);
|
||||
if (stoplightMenuSemaphore == NULL ) {
|
||||
panic("stoplight: sem_create failed.\n");
|
||||
}
|
||||
|
||||
stoplight_init();
|
||||
|
||||
for (i = 0; i < NCARS; i++) {
|
||||
|
||||
direction = random() % 4;
|
||||
turn = random() % 3;
|
||||
|
||||
snprintf(name, sizeof(name), "Car Thread %d", i);
|
||||
|
||||
switch (turn) {
|
||||
|
||||
random_yielder(PROBLEMS_MAX_YIELDER);
|
||||
|
||||
case 0:
|
||||
err = thread_fork(name, NULL, gostraight, stoplightMenuSemaphore, direction);
|
||||
break;
|
||||
case 1:
|
||||
err = thread_fork(name, NULL, turnleft, stoplightMenuSemaphore, direction);
|
||||
break;
|
||||
case 2:
|
||||
err = thread_fork(name, NULL, turnright, stoplightMenuSemaphore, direction);
|
||||
break;
|
||||
}
|
||||
if (err) {
|
||||
panic("stoplight: thread_fork failed: (%s)\n", strerror(err));
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < NCARS; i++) {
|
||||
P(stoplightMenuSemaphore);
|
||||
}
|
||||
|
||||
sem_destroy(stoplightMenuSemaphore);
|
||||
stoplight_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user