cs50300:fall16:lab1

DUE: Tuesday, September 6th 11:59 PM

By the end of this lab students will be able to:

  • Understand how to create processes in XINU and pass parameters to them
  • Create multiple processes that all need to access a shared buffer
  • Perform process synchronization using semaphores to provide mutual exclusion to a shared resource

Your task is to create a producer-consumer system that consists of one or more producer processes and one or more consumer processes and a single shared storage location that has finite capacity. Each producer repeatedly inserts a set of N items into the shared storage and then delays for a specified time before inserting the next set. Each consumer repeatedly extracts a set of K items from the shared storage and then delays for a specified amount of time before extracting the next K items. Each producer and each consumer is implemented by a Xinu process.

A producer has the following properties:

  • The producer is given a label that consists of a single character used to label items produced and in the output to identify the producer.
  • The producer is given an integer that specifies the number of items to insert during each time interval.
  • The producer is given an integer that specifies the number of milliseconds to delay between each interval.

Each consumer has the following properties:

  • The consumer is given a label that consists of a single character and is used in the output to identify the consumer.
  • The consumer is given an integer that specifies the number of items to extract during each time interval.
  • The consumer is given an integer that specifies the number of milliseconds to delay between each interval.

The requirements of your system are:

  • Producers and consumers must run concurrently, using a shared common buffer
  • To ensure that a consumer does not try to consume an item that has not yet been produced, the processes must coordinate.
  • To ensure that multiple consumers do not extract the same item from the shared buffer, consumers must synchronize among themselves.
  • To ensure that multiple producers do not insert multiple items into the same place in the shared buffer, producers must synchronize among themselves.
  • The shared buffer has a fixed size; a consumer must wait (block) if the buffer is empty, and a producer process must wait (block) if the buffer is full.
  • You system must keep a record of:
    • The number of items each producer inserts into the shared buffer, and
    • The number of items each consumer extracts from from each producer.

Your task is to implement the producer-consumer system in Xinu.

In /homes/cs503/xinu there is a file called xinu-fall2016-lab1.tar.gz that contains a start to the code for this lab. Change to your home directory (or whatever directory you'd like to use as a starting point for the lab) and unpack the tar file using the following command:

tar zxvf /u/u3/cs503/xinu/xinu-fall2016-lab1.tar.gz

Untarring the file will create a directory called xinu-fall2016-lab1.

Along with the main code for XINU, this tarball contains the following files:

  • include/prod_cons.h - parameter declarations for the producer/consumer code
  • system/prod_cons.c - function declarations for the producer/consumer code
  • system/main.c - the main XINU process

Your task is to complete these functions to perform the requirements specified in the previous section.

Contents of ''prod_cons.h''

The prod_cons.h file contains the parameters for the simulation. Feel free to change these parameters during testing of your code, but do not place any variables specific to your implementation in prod_cons.h. As part of grading the teaching assistants will replace prod_cons.h for each test case.

Values defined in prod_cons.h:

  • NPRODUCERS - the number of producer processes. You can assume the value will always be greater than zero.
  • NCONSUMERS - the number of consumer processes. You can assume the value will always be greater than zero.
  • BUFFERSIZE - the size of the shared buffer. You can assume the value will always be greater than zero.
  • producer_tags - an array of tags for the producer processes. The tag for the first producer is producer_tags[0]. The tag for the second producer is producer_tags[1], etc. This array will always be NPRODUCERS in size.
  • producer_sleep_times - an array of values representing the time a producer sleeps between creating items. The values are specified in milliseconds (ms). The sleep time for the first producer is producer_sleep_times[0]. The sleep time for the second producer is producer_sleep_times[1], etc. The array will contain exactly NPRODUCERS locations.
  • producer_counts - an array of values representing the number of items each produce creates at each time interval. The number for the first producer is producer_counts[0]. The value for the second producer is producer_counts[1], etc. The array will contain exactly NPRODUCERS locations.
  • consumer_tags - an array of tags for the consumer processes. The tag for the first consumer is consumer_tags[0]. The tag for the second consumer is consumer_tags[1], etc. This array will contain exactly NCONSUMERS locations.
  • consumer_sleep_times - an array of values representing the time each consumer sleeps before deleting more items. The values specified are in milliseconds (ms). The sleep time for the first consumer is consumer_sleep_times[0]. The sleep time for the second consumer is consumer_sleep_times[1], etc. The array will contain exactly NCONSUMERS locations.
  • consumer_counts - an array of values representing the number of items each consumer deletes before returning to sleep. The value for the first consumer is consumer_counts[0]. The value for the second consumer is consumer_counts[1], etc. The array will contain exactly NCONSUMERS locations.

Contents of ''prod_cons.c''

The file prod_cons.c file contains the function declarations for 3 functions that you must implement:

  • void start_prod_con(void) - an initialization function that creates all necessary processes and starts the producer/consumer simulation running. For now, set the process priority for all producers and consumers to the same value, 20.
  • void stop_prod_con(void) - stops the simulation.
  • void print_report(void) - prints the report as described below.

You are required implement the bodies of these functions. Any additional global variables that need to be created for your simulation should be added to prod_con.c as needed.

Each item that a producer generates contains the 1-character label assigned to the producer (which is how a consumer can tell which producer inserted a given item into the shared storage location).

NOTE: Do not put variable declarations specific to your implementation in prod_cons.h because prod_cons.h will be replaced by the test cases for testing your code. Put all dependent code only in prod_cons.c.

NOTE: Do not put any dependent code in main.c because main.c will also be replaced by the test cases for testing your code. Put all dependent code only in prod_cons.c.

As mentioned earlier, your code must keep track of:

  • How many items each producer inserts into the shared buffer
  • How many items each consumer extracts from the buffer from each producer

At the end of the simulation output a report of the counts along with the contents of the shared buffer.

The report looks like this:

Producer A: created xxxxx items
Producer B: created xxxxx items
Producer C: created xxxxx items

Consumer a: deleted XXX items from producer A, XXX items from producer B, and XXX items from producer C
Consumer b: deleted XXX items from producer A, XXX items from producer B, and XXX items from producer C
Consumer c: deleted XXX items from producer A, XXX items from producer B, and XXX items from producer C
  
The shared buffer contains: xxxxx items from producer A, xxxxx items from producer B, and xxxxx items from producer C

NOTE: At the end of the simulation the number of items created and deleted should add up accordingly to ensure that extra items were not produced nor were extra items consumed. For example, the number of he items created by producer A minus the number of items left in the shared buffer from producer A should equal the sum of all items deleted by consumers from producer A.

In your initial implementation, all processes are created with a priority of 20. Experiment with changing the process priorities:

  • The producers have higher priority than the consumers
  • The consumers have higher priority than the producers
  • Each consumer has a unique priority value
  • Each producer has a unique priority value

Compare the results by looking at the statistics from print_report. Does changing the process priorities of producers and consumers affect “fair” access to the shared buffer? If so, how? Be sure to give a description using experimental results and make sure you explain your definition of “fair”.

Submit using the turnin command (see below) your complete source code (all of XINU) including the any files you added to complete the lab. In the system directory include a PDF file called lab1_analysis.pdf with a report discussing:

  • The details behind your implementation. As part of this discussion write answers to the following questions:
    • How does your solution guarantee that only one process will attempt to delete an item at a given time?
    • In your solution, when a producer needs to insert an item in the shared buffer, are consumers also excluded, or can consumers continue concurrently? Explain.
    • When a consumer starts to extract items, does your system guarantee that the consumer will receive contiguous locations in the shared buffer, or do consumers contend for items? Explain.
  • The steps you took to complete the requirements
  • Your results from the extra credit experiment

NOTE: Make sure you put your name on your report, that the file is named exactly as specified, and the file located in the directory specified.

To turn in your lab use the following command

turnin -c cs503 -p lab1 xinu-fall2016-lab1

assuming xinu-fall2016-lab1 is the name of the directory containing your code.

If you wish to, you can verify your submission by typing the following command:

turnin -v -c cs503 -p lab1

Do not forget the -v above, as otherwise your earlier submission will be erased (it is overwritten by a blank submission).

Note that resubmitting overwrites any earlier submission and erases any record of the date/time of any such earlier submission.

We will check that the submission timestamp is before the due date; Any submission past the due date will be deducted the appropriate number of grace days. If submission is beyond your remaining number of grace days, your work will not be accepted.

  • cs50300/fall16/lab1.txt
  • Last modified: 2016/08/29 13:49
  • by lembkej