CS520
Programming Assignment 4
Fall 2018
Due Wednesday October 31


Implement goroutines and channels for the Linux Intel 64 architecture.

  1. The first step (60 points) is to implement these three primitives:

    When the main goroutine exits, then the program exits and all created goroutines are therefore terminated. When a created goroutine returns from its given function, then the goroutine is terminated, it is removed from the list of active goroutines, and any associated memory should be freed. Normally the next goroutine in the list of active goroutines should now execute. If there are no other active goroutines, then a panic is issued.

    A panic is issued by implementing and calling this function:

    // print a formatted error message to stderr and terminate the program
    void panic(char *format, ...)
    {
      va_list ap;
      va_start(ap, format);
      vfprintf(stderr, format, ap);
      fprintf(stderr, "\n");
      exit(-1);
    }
    
    This function outputs an error message to stderr, where the message string is formatted like in a call to printf. (To support this function, you need to include stdarg.h.)

    When implementing any of the primitives for this assignment, if memory cannot be allocated, issue a panic.

  2. The second step (40 additional points) of this assignment is to add the following primitives in order to implement bidirectional Go channels:

    Put a magic number in a 32-bit integer at the front of the struct you used to represent a channel. Use this magic number to perform a rudimentary validation check in the primitives that accept a parameter for a handle for a channel. Use a magic number that is unlikely to appear randomly. (For instance, do not use zero for your magic number.) If a handle cannot be validated, issue a panic.

    The Go language has a notion of a nil channel. We represent this with NULL.

    The first 20 points for this section of the assignment will be awarded by evaluating your implementation of zero-capacity channels.

If at some point in the execution of a program there are no goroutines ready to run, then this is deadlock. You should detect this situation and cause a panic.

Your implementation should be performed using both C and Intel 64 assembler. Use C for as much of the code as possible and only use assembler when necessary. Place the C code in a file called goroutines.c and place the assembler code in a file called asm.s.

You should use valgrind to verify that you properly free all allocated memory. However, be aware that the tricks we are using to implement goroutines confuses valgrind with respect to memory reference errors. It apparently issues spurious read and write error messages in this case.

The directory ~cs520/public/prog4 contains test programs (and a Makefile) that you can link with your code. Use these files to start your testing, but you may need to create other files in order to do thorough testing.

Your program will be graded primarily by testing it for correct functionality. However, you may lose points if your program is not properly structured or adequately documented. Remember that with assembly language, documentation is even more important than with C programs.

Please turn-off any debugging code before you submit your program.

Your program will be graded using agate.cs.unh.edu so be sure to test in that environment. Your programs will be compiled using these gcc flags: -g -Wall -std=c99.

Your programs should be submitted for grading from agate.cs.unh.edu. To turn in this assignment, type:
~cs520/bin/submit prog4 goroutines.c asm.s

Submissions can be checked by typing:
~cs520/bin/scheck prog4

This assignment is due Wednesday October 31. The standard late policy concerning late submissions will be in effect. See the course overview webpage.

Remember: as always you are expected to do your own work on this assignment. Copying code from another student or from sites on the internet is explicitly forbidden!


Last modified on October 10, 2018.

Comments and questions should be directed to pjh@cs.unh.edu