CSE 532S Lock Free Data Structures 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 Lock Free Data Structures 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 lock_free).

    In the main C++ source code file for the project (which should be named something like lock_free.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 * [])

    Implement the basic lock free stack shown in Listing 7.2 of [Williams], declare an instance of it parameterized with int in your main function, call its push method a few times with different integer values, and then have main return 0 to indicate success. Build and run your program, and as the answer to this exercise please explain why the push method's while loop does not need to repeat the statement just before it that loaded the value of the atomic head pointer into the new node's next pointer (i.e, why does it only contain an invocation of the compare_exchange_weak method?).

  3. Update your code from the previous exercise to implement the (leaky) stack implementation given in Listing 7.3 of [Williams], including updating the node struct, adding the pop method, etc. In your main function, call different sequences of push and pop and print out the values that were pushed and popped when you did that. Build and run your program, and confirm that all values pushed were subsequently popped once the stack became empty again. As the answer to this exercise please show your code and the output your program produced.

  4. Update your main function from the previous exercise so that it spawns two threads, one of which pushes an ascending sequence of odd numbers (1 then 3 then 5 etc.) onto the stack and then pops off as many numbers as it pushed, and stores them in a distinct container that is accessible to main. The second thread should do the same thing, but with an ascending sequence of even numbers (0 then 2 then 4 etc.) and also with its own distinct container into which it stores the values it pops. The main function should then join with both of the threads, and print out the values that are in each of the containers.

    Build and run your program and as the answer to this exercise please indicate whether you saw evidence of the threads' pushes and pops interleaving in interesting ways. For example, did either of the containers end up with both even and odd numbers? Please describe what you saw and what it means for how the threads accesses to the lock free stack were interleaved.

  5. Implement the final version of the lock free stack with reference counting and relaxed atomic operations shown in Listing 7.12 of [Williams] and repeat the previous exercise with it.

    Build and run your program, and as the answer to this exercise describe whether you saw any differences in the program's behavior compared to in the previous exercise, and if so what they were.

  6. Modify your code from the previous exercise so that instead of using relaxed atomic operations it uses strict sequentially constistent operations.

    Build and run your program, and as the answer to this exercise describe whether you saw any differences in the program's behavior compared to in the previous exercise, and why you think there were or were not.

    Enrichment Exercises (Optional)

  7. Implement some or all of the lock free queue features shown in the subsequent listings in [Williams] Chapter 7, and run similar trials with it as you did with the lock free stack in the previous exercises.

    Build and run your program and as the answer to this exercise describe what you implemented and what results you saw (and any interesting behaviors you noticed) when you did that.

  8. Try out any of the previous exercises on another machine, in another compiler, etc. (e.g., in g++ on shell.cec.wustl.edu). As the answer to this exercise, please describe the platform and compiler you used, whether you noticed any differences in program behavior on it vs. on the windows lab machines, and why you think there were (or were not) any differences.