Project 3 - Jurassic Park

Download as doc, pdf, or txt
Download as doc, pdf, or txt
You are on page 1of 8

Jurassic Park

CS 345 - Project Three

Purpose
Contemporary operating systems are built around the concept of processes or tasks. Tasks may or may not
be related, may or may not affect the state of another task, but usually always need to share resources in a
protected, prioritized, and equitable manner.

Jurassic Park is an inter-process communication and synchronization problem between multiple tasks.
Visitors to the park want to first get a ticket, visit the park museum, take a ride on a park tour car to see the
dinosaurs, and then visit the gift shop before leaving the park. Since the park is on a limited budget, drivers
must perform double duty when not sleeping; selling tickets to the park visitors and driving the tour cars
through the park. Visitors, drivers, and cars are represents by concurrent tasks while an additional task is
used to display the park status every second.

Attempting to coordinate the park activities without bringing about any race conditions is typical of many
queuing problems. A poorly implemented solution could lead to the inter-process communication problems
of starvation and deadlock. For example, the driver could end up waiting to sell a ticket to a visitor while a
loaded tour car could be waiting for a driver, resulting in deadlock. Alternatively, visitors may not decide to
take a tour car ride in an orderly manner, leading to process starvation as some visitors never get the chance
for a ride even though they have been waiting.

Jurassic Park is not unlike real world simulation and control problems such as found in airports, supply
houses, traffic systems, oil tank farms, etc. Each requires multitasking roles involving inter-process
coordination and communication.

Project Description
Visitors try to enter the Jurassic Park at random times. (Only a set number of visitors may be in the park at
any one time – OSHA requirements!) Upon being allowed in the park, a visitor must get in line to purchase a
ticket. After successfully obtaining a ticket from a driver, the visitor gets in the museum line. (Again, a
limited number of visitors are allowed in the museum as well as the gift shop.) After visiting the museum,
the visitor gets in the tour car line to wait until permitted to board a tour car. As a visitor boards a tour car,
he returns his ticket. When the touring car is filled with visitors and a driver is obtained, the car enters
Jurassic Park and follows a guided tour path through the park. When the tour car completes the ride and
pulls into the unloading station, the visitors depart and get into the gift shop line, the driver goes to sleep
awaiting new duties, and the tour car pulls forward to be loaded again. After visiting the gift shop, the
visitors exit the park.

Like the classical dining philosophers and sleeping barber problems, the Jurassic Park exercise shows what
problems can occur in a multitasking multi-user environment, when several tasks try to use the same
resources. For example, in practicality, you can think of the visitors as programs which want to print. The
tour cars and drivers are print spooler resources which have a finite number of slots for printing jobs (limited
memory). If they have nothing to do, they block. As print jobs arrive, print spooler tasks are awakened and
work until all slots are free.

BYU, CS 345 Project Three – Jurassic Park Page 1/8


Project Requirements
The following are important guidelines for programming the Jurassic Park assignment:

1) Use the arguments to the project3 command to optionally specify the number of park visitors.
(The default is 45 visitors.)
2) Add a delta clock to your operating system. The delta clock ticks in tenth-of-a-second increments.
(See Delta Clock.)
3) Create a task for each park visitor (NUM_VISITORS), driver (NUM_DRIVERS), and tour car
(NUM_CARS). These tasks should all run at the same priority level.
4) Update the park data structure variables appropriately as visitor, driver, and car states change. The
park is displayed using the park data struct every second by the jurassicTask task.
5) Each task (visitor, driver, and car) should create its own timing semaphore, which is used for timing
functions (ie, arrival delay, standing in lines, time in gift shop or museum.) The delta clock should
be used to semSignal these semaphores.
6) Park visitors should randomly arrive at the park over a 10 second period. In addition, visitors should
stand in lines for a random time before requesting a ticket or entrance to the museum or gift shop (3
seconds maximum).
7) Use resource semaphores (counting) to control access to the park, the number of tickets available, and
the number of people allowed in the gift shop and museum.
8) Use mutex semaphores (binary) to protect any critical sections of code within your implementation,
such as when updating the delta clock, acquiring a driver to buy a ticket or drive a tour car,
accessing global data, or sampling the state of a semaphore.
9) Use semaphores (binary) to synchronize and communicate events between tasks, such as to awaken a
driver, signal data is valid, signal a mode change, etc.
10) Use at least one semTryLock function in your simulation.
11) The “SWAP” directive should be inserted between every line of code in your Jurassic Park
simulation. Park critical code must be protected by the parkMutex mutex.
12) The park simulation also creates a “lostVisitor” task which sums critical variables in the park to
detect any lost visitors. Beware!
13) Since all project 3 tasks need to be on the same priority level, it is necessary to let the park fully
initialize before proceeding to create your visitor, car, and driver tasks. To that end, execute a
"while (!parkMutex) SWAP;" loop just after the jurassicPark task is created.
14) You are to implement a fair algorithm that prevents deadlock and starvation rather than detect them.

Delta Clock
A delta clock is a mechanism used to improve performance and simplify the management of timed
semaphores. If a linked list (or the equivalent) is used to store pending timed semaphores, then all elements
of the list have to be checked every time there is a clock to see if that semaphore is to be signaled. For a
small number of semaphores, this might be OK, but certainly not a very scalable solution.

A delta clock structure stores pending timed events such that only the first entry needs to be examined (and
updated) when a clock occurs. All other timing events are a function or delta from that first entry.

For example, consider the following timed events:

After 20 clocks, signal Event1


After 5 clocks, signal Event2

BYU, CS 345 Project Three – Jurassic Park Page 2/8


After 35 clocks, signal Event3
After 27 clocks, signal Event4 and Event5
After 22 clocks, signal Event6.

Even One way to handle this is to create a linked list of events and run through the list on every
5 clock. However, notice that after 5 clocks, the first event to occur is Event2. Event1
t2
Even occurs 15 clocks later, Event6 comes 2 clocks after that, Event4 and Event5 occur 5
15
t1 clocks after Event6, and finally, Event3 happens 8 clocks after that. If we capture this
Even information in a delta clock structure, then only the top entry need be decremented on each
2
t6 clock interval. When it tics down to zero, the event is signaled and the delta stack is
Even
5 popped.
t4
Event
0 The delta clock structure is illustrated on the left.
5
Event
8
3

Inter-process Communication
Inter-Process Communication (IPC) refers to the exchange of data among two or more threads in one or more
processes. Among others, IPC techniques involve synchronization (events and semaphores), shared memory
(globals), message passing (pipes and message queues), sockets, and remote procedure calls (RPC). The
method of IPC used may vary based on the bandwidth and latency of communication between the threads,
and the type of data being communicated. For Jurassic Park, consider using semaphores and shared memory.

Semaphores are considered events and are usually one of the following types:

1. Resource semaphores. Typically counting, these semaphores are used to control access to the park,
the number of tickets available, and the number of people allowed in the gift shop and museum.

// create MAX_TICKETS tickets using counting semaphore


tickets = createSemaphore("tickets", COUNTING, MAX_TICKETS); SWAP;

// buy a ticket (consume)


SEM_WAIT(tickets); SWAP;

// resell ticket (produce)


SEM_SIGNAL(tickets); SWAP;

2. Mutex semaphores. Typically binary, these semaphores are used to protect any critical sections of
code within your implementation, such as when updating the delta clock, acquiring a driver to buy a
ticket or drive a tour car, accessing global data, or sampling the state of a semaphore.

// need ticket, wait for driver (mutex)


SEM_WAIT(needDriverMutex); SWAP;
{
// signal need ticket (signal, put hand up)

}
// release driver (mutex)
SEM_SIGNAL(needDriverMutex); SWAP;

BYU, CS 345 Project Three – Jurassic Park Page 3/8


3. Signal semaphores. Typically binary, these semaphores are used to synchronize and communicate
events between tasks, such as to awaken a driver, signal data is valid, signal a mode change, etc. For
example, the following code signals the need for a ticket (needTicket), signals a driver to wakeup
(wakeupDriver), waits for a ticket to be printed (ticketReady), and then signals to buy the
ticket (buyTicket). The task indicates it no longer needs a ticket by consuming the needTicket
semaphore.

// signal need ticket (signal, put hand up)


SEM_SIGNAL(needTicket); SWAP;
{
// wakeup driver (signal)
SEM_SIGNAL(wakeupDriver); SWAP;

// wait ticket available (signal)


SEM_WAIT(ticketReady); SWAP;

// buy ticket (signal)


SEM_SIGNAL(buyTicket); SWAP;
}
// put hand down (signal)
SEM_WAIT(needTicket); SWAP;

Shared memory can be implemented using C global memory when protected with mutex semaphores.

// protect shared memory access


SEM_WAIT(parkMutex); ;SWAP

// access inside park variables


myPark.numOutsidePark--; ;SWAP
myPark.numInPark++; ;SWAP

// release protect shared memory access


SEM_SIGNAL(parkMutex); ;SWAP

Interfacing to “jurassicTask”

The “jurassicTask” task fills tour cars with passengers when a car is in the loading position, moves tour cars
one position forward (if possible) around the park, randomly chooses a route at the route cross roads, and
displays the status of Jurassic Park every second. The display is generated from the following C struct
variables defined in the os345park.h file:

typedef struct
{
int numOutsidePark; // # outside of park
int numInPark; // # in park (P=#)
int numTicketsAvailable; // # left to sell (T=#)
int numRidesTaken; // # of tour rides taken (S=#)
int numExitedPark; // # who have exited the park
int numInTicketLine; // # in ticket line
int numInMuseumLine; // # in museum line
int numInMuseum; // # in museum
int numInCarLine; // # in tour car line
int numInCars; // # in tour cars
int numInGiftLine; // # in gift shop line
int numInGiftShop; // # in gift shop
int drivers[NUM_DRIVERS]; // driver state (-1=T, 0=z, 1=A, 2=B, etc.)
BYU, CS 345 Project Three – Jurassic Park Page 4/8
CAR cars[NUM_CARS]; // cars in park
} JPARK;

Your visitor, driver, and tour car tasks need to update the appropriate variables at the appropriate times. The
following global signal semaphores are defined in “os345park.c”:

Semaphore* fillSeat[NUM_CARS]; SWAP;


Semaphore* seatFilled[NUM_CARS]; SWAP;
Semaphore* rideOver[NUM_CARS]; SWAP;

All car tasks should

1) for each car (and seat in the car),


a. wait (fillSeat) to be filled, seat by seat, when the car is in loading position,
b. get a passenger from the tour car waiting line,
c. signal (seatFilled) that seat has been filled,
2) get a driver for the car,
3) wait for a signal (rideOver) that the ride is over,
4) and then allow driver to go back to sleep.

For example, to fill a seat in tour car carID, wait for available seat ready (fillSeat[carID]), then find
a visitor from the tour car waiting line, and then signal (seatFilled[carID]) that you are ready for the
next seat.

SEM_WAIT(fillSeat[carID]); SWAP; // wait for available seat

SEM_SIGNAL(getPassenger); SWAP; // signal for visitor


SEM_WAIT(seatTaken); SWAP; // wait for visitor to reply
signalWhenRideDone(rider); SWAP; // save ride done signal semaphore
SEM_SIGNAL(passengerSeated); SWAP: // signal visitor in seat

// if last passenger, get driver


{
SEM_WAIT(needDriverMutex); SWAP;

// wakeup attendant
SEM_SIGNAL(wakeupDriver); SWAP;
...
// got driver (mutex)
SEM_SIGNAL(needDriverMutex); SWAP;
}

SEM_SIGNAL(seatFilled[carID]); SWAP; // signal ready for next seat

// if car full, wait until ride over


SEM_WAIT(rideOver[myID]); SWAP;

Park variables correspond to the park display as follows:

BYU, CS 345 Project Three – Jurassic Park Page 5/8


# Waiting to Enter Park Tour Car Line # of Passengers
numOutsidePark numInCarLine park.cars[ ].passengers

Ticket Line
numInTicketLine
Driver Status
park.drivers[ ]
# Tickets Available
numTicketsAvailable

# in Park
numInPark

# Rides Taken
numRidesTaken

# Exited Park
numExitedPark

# in Gift Shop Gift Shop Line # in Museum Museum Line


numInGiftShop numInGiftLine numInMuseum numInMuseumLine

Suggested Steps to Implementing the Jurassic Park Project


1. Implement delta clock.
a. Design data structure to hold delta times/events.
b. Add 1/10 second routine to pollinterrupts. Decrement top event and semSignal when time = 0.
c. Program an insert delta clock routine (insertDeltaClock(int time, Semaphore* sem)).
d. Thoroughly test the operation of your delta clock before proceeding.
2. Develop the car task.
a. Design car functionality and Jurassic Park interface. (Don’t worry about passengers yet.)
b. Implement design and integrate with os345 and Jurassic Park.
c. Observe correct car behavior.
3. Develop the visitor task.
a. Design visitor functionality and car task interface.
b. Implement design and integrate with os345 and car tasks. (Don’t worry about tickets yet.)
c. Use delta-clock to vary visitor time in all lines, museum, and gift shop.
d. Observe correct visitor behavior as a visitor moves through the park.
4. Develop the driver task.
a. Design driver functionality and interface with visitor and car tasks.
b. Implement design and integrate with os345, visitor, and car tasks. (Now is the time to worry
about ticket sales and driver duties.)
c. Add ticket sales and driver responsibilities.
d. When a driver is awakened, use the semTryLock function to determine if a driver or a ticket
seller is needed.

BYU, CS 345 Project Three – Jurassic Park Page 6/8


Grading and Pass-off

Your Jurassic Park assignment is to be demonstrated in person to a TA. The assignment is worth 20 points,
which will be awarded as follows:

1) 15 points – Implement the following functionality:

• 4 points – Implement a delta clock in the pollInterrupts routine (OS345.c) to signal


semaphores after a certain time period, unblocking sleeping tasks. (The delta clock should tick
down every 1/10 of a second.) Make the delta clock generic – able to signal any type of
semaphore, binary or counting. The clock should handle mutual exclusion with insert/delete
routines and not lose any time. Implement functions to insert and delete semaphores from the
delta clock. These routines must properly handle mutual exclusion.
• 3 points – Create a single, re-entrant visitor task that
o tries to enter the Jurassic Park at random times over a 10 second period. (Use a counting
semaphore to restrict the number of visitors in the park to MAX_IN_PARK.)
o upon being allowed in the park, a visitor must get in line to purchase a ticket. (Use a
counting semaphore to restrict the number of available tickets to MAX_TICKETS.)
o after successfully obtaining a ticket from a free driver, the visitor gets in the museum line.
(Again, use counting semaphores to restrict the number of visitors in the museum and gift
shop to MAX_IN_MUSEUM and MAX_IN_GIFTSHOP respectively.)
o after visiting the museum, the visitor gets in the tour car line to wait until permitted to
board a tour car. (Release visitor ticket after boarding tour car.)
o when the touring car ride is over, the visitor moves to the gift shop line.
o after visiting the gift shop, the visitor exits the park allowing another visitor into the park.
• 3 points – Create a single, re-entrant car task, which acquires (NUM_SEATS) visitors as it
waits (fillSeat) and fills (seatFilled) requested car seats, acquires a driver, waits
(rideOver) until the park ride is over, and then releases the driver/visitors as described above.
• 2 points – Create a single, re-entrant driver task, which waits to be awakened and then either sells
a visitor a ticket or else fills a driver seat in a car and waits until the ride is over. Use the
semTryLock function to acquire the correct resource semaphore. (The driver task controls
ticket access using a resource semaphore.)
• 1 point – Use resource semaphores (counting) to control access to the park, the number of tickets
available, and the number of people allowed in the gift shop and museum.
• 1 point – Use mutex semaphores (binary) to protect any critical sections of code within your
implementation, such as when updating the delta clock, acquiring a driver to buy a ticket or drive
a tour car, accessing global data, or sampling the state of a semaphore.
• 1 point – Use signal semaphores (binary) to synchronize and communicate events between tasks,
such as to awaken a driver, signal data is valid, signal a mode change, etc.

2) 5 points – Have the project3 command schedule the jurassicTask. Also schedule 4 driver tasks, 4
car tasks, and 45 visitor tasks. All Jurassic Park tasks should execute at the same priority level.
Observe proper behavior as all visitors visit the museum, take a tour car ride, visit the gift shop, and
exit the park. Make sure that a SWAP directive is placed after every C instruction in your Jurassic
Park visitor, car, and driver simulation code (not kernel routines) as well as any non-kernel Delta
Clock code. These context switches will verify that mutual exclusion is properly implemented for a
truly pre-emptive environment.

Your task allocations might appear as follows:


BYU, CS 345 Project Three – Jurassic Park Page 7/8
# Task Name Priority Blocking Semaphore
0 myShell 5 inputCharReady
1 jurassicPark 5 moveCar
2 displayPark 5 tics1sec
3 lostVisitor 5 -
4-7 driver(01-04) 5 wakeupDriver
8-11 car(01-04) 5 fillxSeat
12-56 visitor(01-45) 5 timeEventxx

3) In addition to the possible 20 points, the following bonus/penalties apply:

• +2 points – bonus for early pass-off (at least one day before due date.)
• +1-6 points – bonus for approved changes to os345park.c, such as:
 Improved interface to park
 Different routes in park
 Making dinosaurs individual tasks
 Random lost (or consumed) park visitors (must be accounted for)
 Gift shop expenditures
 Having drivers do periodic maintenance on park ride
 Something you think is clever…
• –2 points – penalty for not running visitor, car, and driver tasks at same priority level.
• –2 points – penalty for altering os345park.c without approval.
• –10 points – penalty for not having a SWAP after every C line of code.
• –2 points – penalty for each school day late.

BYU, CS 345 Project Three – Jurassic Park Page 8/8

You might also like