Producer Consumer Project

by: burt rosenberg
at: university of miami
date: oct 2015
Updated consumer behavior for those who have not yet submitted and have questions.

Because this is a late fix to the requirements, I accept any reasonable behavior for the consumer. I suspect what people did is either implement fixed behavior which is now either the -n 0 default (loop forever until ^C) or -n 1 (get one message then exit).

Note also: A ^C will probably require you to reboot your computer, to resynchronize the monitor. That's ok if you have to.

NAME
    producer, consumer
    
SYNOPSIS	
    producer [-vM] [-r _num_] [-n _num_] _message_
    consumer [-vM] [-r _num_] [-n _num_]
    
DESCRIPTION
    Using a ring buffer and a monitor implement a thread-safe produce-consumer system.
    
    The _message_ argument is a collection of messages that is sent by the producer and
    received by the consumer. 

    When not in Message Mode, the messages are the individual characters of _message_.
    Each character is sent and received independently.
    
    In Message Mode, _message_ is parsed on the "." character and each parsed component 
    is a single message and is sent in its entirety. In Message Mode  the "." is not sent.

    In Message Mode the consumer prints each message on its own line; else it prints
    the characters without new lines.
    
    The following options are available:
        -n     - producer repeats _num_ times the sending of all messages in _message_.
                 consumer consumes n messages before exiting. If _num_ is 0, producer and
                 consumer repeat forever. Default is _num_ is 0.
        -r     - sleep interval between productions/consumptions, in seconds. 
                 Default sleep time is 1 second.
        -v     - verbose output (useful for debugging)
        -M     - Message Mode. 
                 Interpret _message_ as a "." delimited sequence of "words".
                 Each word is sent and received completely.
    
    Although producer and consumer can use any algorithm to send in Message Mode,
    one method is to use the emptiness of the ring buffer as the delimiter of words.
    The producer will not send unless the buffer is empty, and when it sends it sends 
    each word completely while holding the monitor. The consumer receives each word 
    completely by reading until empty buffer while holding the monitor.

HISTORY
    An in-kernel monitor to implement Producer-Consumer first appeared in CSC 521 as 
    Assignment 3-a in the Fall, 2010-2011. Combining the monitor with the ring buffer
    appeared in Project 3, CSC421, 2014-2015.

BUGS
    In Message Mode the individual messages must be not larger than the ring buffer size.
    Without a ring buffer IOCTL to query ring buffer size, producer will assume the size 
    is at least 8 characters.
    
    It is difficult to reset the in-kernel monitor, and rebooting the operating system
    might be needed after an incomplete run of the Producer-Consumer.
    
    Original documentation did not specify the -n option for the consumer, nor the 
    default behavior for what -n controls.

Goals

The goals of this project are:

Discussion

Use your monitor in the solution to the Producer-Consumer problem. See the blog post on this topic.

The idea is to embed the ring buffer in the monitor.

Your code must first to enter the monitor. The call to my_monitor will block if the monitor is busy. No ring buffer commands should be issued unless the process issuing the commands is in the monitor. Depending on the situation, if the process cannot complete the enqueue or dequeue, because the ring buffer is full or empty, it can issue a wait operation on the monitor. When it is notified it again checks if the enqueue or dequeue can be completed. If the operation proceeds it then leaves the monitor, else it can wait again.

Your producer.c file should implement the function:

    int producer(char * s, int is_mm) { 
       /* 
          is_mm is 1 if in Message Mode, 0 otherwise
          
          If in Message Mode, s is a string, i.e. a null terminated sequence 
          of characters, of length not greater than RING_BUFFER_LENGTH.
          Else s points to a single character.
          
          Returns 0 having enqueued the message in s. On error return -1.
          
          May sleep waiting for room in the ring buffer.
        */
       
       /* implement */
       
     } 
Your consumer.c file should implement the function:
    int consumer(char * s, int is_mm) {
        /*
            is_mm is 1 if in Message Mode, 0 otherwise.
            
            If in Message Mode, s is a buffer of size large enough to hold 
            RING_BUFFER_LENGTH characters and a null terminator. 
            Else s points to a buffer of size large enough to hold a single character.
            
            Returns 0 having dequeued the message into s, including a null terminator. 
            On error return -1.
           
            May sleep waiting for messages in the ring buffer.
         */
         
         /* implement */
         
    }

Your producer and consumer codes are two separate programs producer.c and consumer.c. Link them to the library my_systemcalls.a which contain syscalls to the kernel operations. To create the .a file, read man ar and modify the my_syscalls.a target in the Makefile. Please submit your modified makefile as part of the assignment deliverables.

The Program Library HOWTO might be useful.

Refer to class/proj6 for various files helpful to start the project, and necessary to test the project and submit the project in the required format.

Your project should be in your [username]/proj6 directory. See the Makefile for the required names of files in the proj6 directory.

To submit

  1. The my_syscalls.c and my_syscalls.h files, although you probably do not have to modify them form the provided versions.
  2. The Makefile, which you will modify the my_syscalls.a target.
  3. The producer.c and consumer.c files.
  4. Your kernel__mysyscalls.c file.
Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.

author: burton rosenberg
created: 26 oct 2015
update: 27 oct 2015