                           _________________

                            HW 12 QUESTIONS
                           _________________


Write your answers to the questions below directly in this text file to
prepare for the associated quiz. Credit for the HW is earned by
completing the associated online quiz on Gradescope.


PROBLEM 1: The Setup
====================

A
~

  Compile and run `worm_pthread.c' using the provided Makefile. Make
  sure to follow the program prompts.  Describe what you observe as the
  program runs on the terminal.

  Note: when compiling code that uses PThreads library functions, link
  against that library via `-lpthread'.


Solution                                                      :solution:
--------

  Compiling and running the program shows the following prompts/output.

  ,----
  | > gcc worms_pthread.c -lpthread
  | > ./a.out
  | Running worm threads...
  | eeeE...lLl
  | .e......ll
  | ........ll
  | .......lll
  | ........ll
  | ...aa.....
  | ..aaa....g
  | ..aaaA...G
  | ..a......g
  | aaa......g
  | 
  | E @ ( 0, 3) : step   8 /  50 territory:  5
  | A @ ( 7, 5) : step  16 /  50 territory: 13
  | G @ ( 7, 9) : step   7 /  50 territory:  4
  | L @ ( 0, 8) : step  42 /  50 territory: 12
  | 0 worms finished
  `----

  with a constantly updating board that eventually terminates with an
  appearance like:

  ,----
  | Running worm threads...
  | Eellllllll
  | eelllggl..
  | ealllggl..
  | aa.llggg..
  | aaa.llggg.
  | aaaa.llggg
  | aaaa.Llggg
  | .a.aa...gg
  | aa..aa..Gg
  | aa..Aa..gg
  | 
  | E @ ( 0, 0) : step  50 /  50 territory:  5
  | A @ ( 9, 4) : step  50 /  50 territory: 25
  | G @ ( 8, 8) : step  50 /  50 territory: 22
  | L @ ( 6, 5) : step  50 /  50 territory: 24
  | 4 worms finished
  | All threads complete.
  `----


B
~

  Examine the code and describe the types data associated with each of
  the following elements in the program.
  - The "board" which has several pieces of data
  - The "worms" which have several pieces of data


Solution                                                      :solution:
--------

  - The board is comprised of a global 2D array of characters for
    display along with a 2D array of mutexes used to coordinate access
    to cells
  - The worms have worm_t struct associated with them that tracks
    various pieces of data such the character associated with the worm,
    a delay for the "speed" of the worm, starting row/col, and so
    forth. There is an array of 4 of these structs declared as a global
    variable.


C
~

  Describe the area of code in `main()' which creates threads and awaits
  them finishing.
  - Describe the function which is used to start a thread running and
    its arguments. Consult the manual for documentation on this function
    if needed.
  - Describe the function which is used to wait until a thread finishes.


Solution                                                      :solution:
--------

  - pthread_create() is used to create a thread. This function takes 3
    important arguments: a pointer to a data type `pthread_t' for the
    parent to track the child, a function for the child to start
    running, and a pointer to an argument to the child.  It is used in
    `main()' to create 4 child threads which run the `worm_func()'
    function and 1 thread run `print_func()'.
  - pthread_join() causes a thread to wait for the completion of another
    thread and is used in `main()' to wait for the child threads to
    complete.


PROBLEM 2: The Worms
====================

A
~

  Examine the `worm_func()' function carefully.  You may wish to
  consider the specific data passed to these worms which are in the
  array of `wormparam_t' structs near the top of the source code.

  Describe the basic algorithm that worms follow to do their work.


Solution                                                      :solution:
--------

  - Worms start on a 2D board of chars at an initial position; they
    write their display character at this position
  - Each worm iterates NSTEPS times
  - A move can be up/down/left/right on the 2D board of characters
  - The worms try random moves among these 4 to place a character on the
    2D board representing them.
  - Past areas that the worm occupied are marked with lower case chars
    while an upper case char is the current row/col position
  - Worms do not move into other worm territory, only unoccupied '.'
    spaces or their own areas
  - On completing NSTEPS moves, worms exit


B
~

  Describe how worms avoid both claiming the same piece of
  territory. What system call mechanism is used to ensure that two worms
  cannot claim the same area of the board? Describe the function calls
  that are used to accomplish this and what functions in `main()' are
  used to set up this coordination mechanism.


Solution                                                      :solution:
--------

  Each area of the board is associated with a mutex, a mutual exclusion
  lock with type `pthread_mutex_t'.  These are used with the calls
  `pthread_mutex_lock()' to lock a cell in the board. This ensures that
  only a single worm at a time is examining a given cell and can claim
  it.  After examining the cell and deciding on a appropriate action
  (move or not) the worm will unlock the mutex via
  `pthread_mutex_unlock()' to allow other worms to investigate it.

  Before the worms can use the mutexes, `main()' creates a 2D array of
  them via `pthread_mutex_init()' and then cleans up the mutexes later
  with `pthread_mutex_destroy()'.


C
~

  Describe the logic that appears to cause worms to be 'fast' and
  'slow': how is this artificial speed actually created in the
  `worm_func()' code.

  While the speed differences of worms is an intended creation of the
  program, speculate as to what use threads can be when dealing with
  entities of different speeds.


Solution                                                      :solution:
--------

  Each worm is given a `delay' parameter which is used to sleep the
  thread. In this case `usleep()' is used to sleep for a specified
  number of microseconds as the `sleep()' function must take an integer
  number of seconds.  Sleeping for a short delay makes worms run fast
  while longer delays make them appear slower.

  In real programs, the threads may represent different computations
  that take more or less time or they be spun up to deal with external
  events like I/O from clients that run a unpredictable
  rates. Individual threads may stall without affecting the execution of
  other parts of the program.


Optional: The Printer
=====================

  The printing thread runs `print_func()'. This does not introduce any
  new concurrency techniques. However it does use some special display
  tricks, printing extremely strange output like
  ,----
  |   printf("\33[s");              // save cursor position
  |   printf("\33[?25l");           // hide cursor to avoid flicker
  |   printf("\33[u");              // restore cursor position
  `----
  This type of output also appears in some other places in the program.
  The strange looking characters are special sequences for *terminal
  control*. The program interpreting output can be manipulated in
  various ways to change the cursor position, color of text, and so
  forth.  This is an extremely old set of conventions that harkens back
  to a day when these special sequences would physically manipulate
  aspects of the machine in which they appeared.  Modern "terminal
  emulators" such as Gnome Terminal or XTerm which show a command line
  honor these conventions making it possible for programs to display
  information in the same position as is done here or take over the
  entire screen of the terminal such as vi and gdb do.

  Discussion of terminal control is beyond the scope of our course but
  does receive some treatment in Stevens/Rago and elsewhere.  You can
  read more about the history and insanity of terminal control and the
  escape sequences that give some control over them in
  <https://en.wikipedia.org/wiki/ANSI_escape_code>

  To program a more fully-featured terminal program, use a robust
  terminal control library such as ncurses.
  <https://en.wikipedia.org/wiki/Ncurses> This library is used in the
  below Python version of the worms program.


Optional Enrichment: Threads in Python
======================================

  Threads are not unique to C and the Pthreads library. Most modern
  programming environments include some version of them. The prototype
  version of the worms program was written in Python and can be found in
  `worms.py' and can be run via
  ,----
  | > ./worms.py
  `----

  - No territory or step numbers are tracked in the Python version; it
    runs until Ctrl-c is pressed
  - The `curses' library is used to manipulate the terminal screen which
    allows for boxes and color to be used but complicates the
    implementation somewhat.
  - Python features several types of mutual exclusion locks including
    one used here that can be re-locked by the same thread without
    negative effects.

  Time permitting, explore the code of `worms.py' and draw some
  parallels as to the C code.
