CSE 532S Monitor Object Studio

Please complete the required studio exercises listed below, along with any of the (optional) enrichment exercises that interest you.

As you work through the exercises, please record your answers in a file, and upon completion please e-mail your answers to the cse532@seas.wustl.edu course e-mail account with Monitor Object Studio in the subject line.

Please make sure that the name of each person who worked on these exercises is listed in the first answer, and that you number your answers so they are easy for us to match up with the appropriate exercise.


    Required Exercises

  1. As the answer to the first exercise, list the names of the people who worked together on this studio.

  2. Open up Visual Studio 2013, make sure your settings are for C++, and create a new project for this studio (for example named something like monitor_object).

    In the main C++ source code file for the project (which should be named something like monitor_object.cpp) please modify the main function signature so that it looks like the standard (i.e., portable between Windows and Linux) main function entry point for C++: int main (int, char * [])

    In a separate header (and possibly source) file, declare and define a synchronized_list class template parameterized with a data type parameter T, which has an STL list of T as a private member variable, a public default constructor, and public push_back, pop_back, push_front, and pop_front methods corresponding to the methods of the STL list member variable (the pop methods should return the value that was on the appropriate end of the list), and that simply call their equivalents in the STL list class template (the pop methods also will need to peek at the appropriate end of the list and store the value locally before popping the list).

    In your main function, declare an instance of your class template (on the stack) parameterized with int, push multiple integer values into it, and then pop all of the values from it, printing each value out to the standard output stream.

    Build your program and run it from a windows terminal shell and confirm that the numbers printed out are correct. As the answer to this exercise, please show the code you wrote and the output your program produced.

  3. Modify your code from the previous exercise so that instead of all being run sequentially in the main function, many pushes into the front of the list are run in different C++11 threads. Have the main thread join with those threads after launching them, and then pop all the values from the back of the list and print them out to the standard output stream.

    Build and run your program and as the answer to this exercise (1) show the code that runs the sequences in the different threads, (2) show the output your program produced, and (3) describe any differences you saw in how the program behaved in this exercise, compared to in the previous one.

  4. Modify your code from the previous exercise so that instead of being done in the main function, many pops from the back of the list are run in different C++11 threads (each of which prints out the value it just popped when it does so) - have the main thread simply join with those threads after launching them.

    Build and run your program and as the answer to this exercise (1) show the code that runs the sequences in the different threads, (2) show the output your program produced, and (3) describe any differences you saw in how the program behaved in this exercise, compared to in the previous one.

  5. Modify your code to use a std::mutex, a std::unique_lock, and a std::condition_variable to synchronize the methods of the synchronized_list class template according to the Monitor Object Pattern, as follows:

    • before and after pushing into the list the appropriate methods of the synchronized_list class template should acquire and release the std::mutex, and should notify all waiting threads before releasing; and

    • the appropriate methods that pop from the list should use the std::unique_lock and std::condition_variable to wait until the list is non-empty, wake up and acquire the mutex, pop from the list and print the value, and then release the lock and wait again for the condition to become true again.

    Build and run your program and as the answer to this exercise (1) show the modified class declaration and definition code, (2) show the output your program produced, and (3) describe any differences you saw in how the program behaved in this exercise, compared to in the previous one.

  6. Add size_t member variables to your synchronized_list class template, to enforce high and low water marks for the allowed size of the queue during an operation (though if 0 they mean that any size is allowed); the default constructor should initialize both of them to 0, and you should provide another constructor that initializes them from passed values.

    If the high water mark is greater than 0, the push methods should wait until the queue size is less than or equal to the high water mark before proceeding, and the pop methods should always make sure that the queue size is both non-zero and greater or equal to the low water mark before proceeding.

    Build and run your program, and as the answer to this exercise show the parts of your code that changed to provide this capability.

    Enrichment Exercises (Optional)

  7. Modify your code from the previous exercises so that waits are done for relative or absolute time intervals. Build and run your program, and as the answer to this exercise please show your modified code.

  8. Modify your code so that threads do multiple pushes or pops each time they have the lock, but always respect the high and low water marks. Build and run your program, and as the answer to this exercise please show your modified code.