(Last revision 10/27/99)
10/27/99: Revised the due dates.
CS 3750 First C Programming Assignment (prog #1)
Due Thursday, October 28
-- psuedo-code description of the algorithm for your solution.
Due Tuesday, November 09 (in two separate e-mail messages --
please no "enclosures" or attachments.")
-- the completed program source code in one e-mail message
-- one or more script(s) documenting thoughtful, adequate,
intelligent testing
1. Look over the contents of the directory "ThreadInfo" in our
web space. Read the file HiHo.c in that directory. It
illustrates everything you need to know about using function
calls from the C threads package on the NeXT's, and about using
the queuing semaphores implemented by the sem.c and sem.h
files. Make copies of sem.c and sem.h for your own use. (We
will go over this in class.)
2. Use the queuing semaphores to implement a "cheerleader
pyramid" program that spawns 10 cheerleaders (threads), assigns
each of them a position in the pyramid, and causes them each to
execute a C function which writes a message to standard output
when they take their position in the pyramid.
Just as a real pyramid must be built from the ground up, so
must be the pyramid created by the threads in your program.
The threads will have serial numbers 1, 2, 3, 4, 5, 6, 7, 8, 9,
and 10. The pyramid they are trying to build looks like this:
01
02 03
04 05 06
07 08 09 10
Thread #1 cannot join the pyramid until threads #2 and #3 are
in position. Thread #2 cannot join until threads #4 and #5 are
in position. Similarly, #3 must comes after #5 and #6, #4
after #7 and #8, #5 after #8 and #9, and #6 after #9 and #10.
It will be the job of your program to synchronize the
activities of the threads and to see to it that the messages
the threads write come out in an order consistent with the
constraints above.
The synchronization that accomplishes the above must be done by
employing the semaphore data types implemented by the files
sem.c and sem.h. You don't get credit if you don't use
semaphores to do this.
In *addition* to the constraints mentioned above, imposed by
the shape of the pyramid, there is also a need to enforce
mutually exclusive access to standard output. The constraints
above are not enough to guarantee that (say) thread #4 will not
try to write its message concurrently with #6. This could
cause output from #4 and #6 to be written to the screen in a
jumbled interleaving.
We want the message of each thread to be written atomically, on
its own separate line of the output. This is really a separate
problem. I will solve this one for you by telling you exactly
what to do. Let's cover that topic in class, since there are
some details I don't want to go into here.
All critical section problems you encounter must be solved in
such a way that the mutual exclusion, progress, and bounded
waiting conditions are all guaranteed. All synchronizations
done must guarantee freedom from all forms of indefinite
postponement.
The program must be written so that there is a "mother" task
which creates the 10 cheerleader threads. The cheerleaders
must notify the mother after they have finished their message,
and then exit. The mother must make sure that all the
cheerleaders have finished with their messages before she exits.
3. Figure out a protocol that allows the mother and threads to
cooperate to do the job indicated above. Once you have decided
on the protocol, write it down in pseudo-code form and e-mail
it to me by the first due date. This design should be in the
form of two or more procedure listings, showing what the
threads and the mother process will be doing while the program
is running.
By the second due date, send a complete, compilable, source
listing with adequate comments (The bottom line on the question
of documentation is that I need to be able to read and
understand your program!) Also, in a separate e-mail message,
send a copy of your test script(s).
(Beware: since some errors in concurrent programs are
timing-dependent, you will need to think of some novel ways to
test your program. The file HiHo.c illustrates this. Ask for
more details in class.) All you have to send me is the main
module, pyramid.c, and I will compile it on a NeXT with my own
copies of sem.h and sem.c, so it will work for me if it worked
for you. For this assignment, you may work in teams of two (2)
people. If you work in a team, make sure that both names are
in your comments!
More Discussion of the Assignment
When you think about doing this assignment, imagine that the
mother thread and each cheerleader thread will run on a
separate CPU of a tightly-coupled multiprocessor. Of course,
our NeXT computing systems are not tightly-coupled
multiprocessors. Nevertheless, the point of this exercise is
for you to write a program that will work on *any* computing
system on which multiple processes can execute concurrently
while sharing variables.
A tightly-coupled multiprocessing system can be diagrammed this
way:
CPU CPU CPU CPU CPU CPU CPU MEMORY
| | | | | | | |
------------------------------------------------------------ BUS
| | | | | | | | |
CPU CPU CPU CPU CPU CPU CPU CPU CPU
Here we have a RAM memory being shared over a common bus by
several CPU's. It is possible that the different CPU's have
radically different speeds. Speed can be affected by the
inherent power of the CPU, or by the current load on the CPU.
Besides that, it is impossible to tell which CPU will be
assigned to which thread. And also, each time we run the
program, the assignment can be different.
In your program, the mother process must create all the
cheerleaders without delay immediately after the program starts
running. The mother must do nothing to direct the creation of
the pyramid. In general it is a bad idea to create "traffic
cop" threads, because the traffic cop too often becomes a
bottleneck. When every action has to be approved by a master,
events can only happen as fast as the master can approve them.
This would defeat the purpose of parallel processing.
The only interactions a cheerleader is allowed to have with its
mother, after its creation, is that each cheerleader will
somehow notify the mother after it has positioned itself in the
pyramid and written its message to standard output. This is
done so that the mother can know when to exit.
The cheerleaders must cooperate among themselves, using
semaphores for synchronization, to create the pyramid. As to
the decision of when a cheerleader X moves into position, only
X and the cheerleaders that will be supporting X are allowed to
participate in the making of that decision.