Submit: Turn in your
entire xinu-hw9
directory source files
using the turnin command
on morbius.mscsnet.mu.edu or one of the other
Systems Lab machines. Please run "make clean" in
the
compile/ subdirectory just before submission to reduce
unnecessary space consumption.
Work should be completed in pairs. Be certain to include both names in the comment block at the top of all source code files, with a TA-BOT:MAILTO comment line including any addresses that should automatically receive results. It would be courteous to confirm with your partner when submitting the assignment.
Make a fresh copy of your work thus far.
cp -R xinu-hw8 xinu-hw9
There is no new tarball for the project. All of your modifications will be made to existing files, or to brand new files that you will create.
For those who do not feel they can continue under the weight of
accumulated bugs from previous projects, we offer the opportunity
to start from a working binary version of most of the solutions.
If you wish to pursue this path, start with untarring the
clean-slate tarball in a working directory:
tar xvzf
~brylow/os/Projects/xinu-hw9-cleanslate.tgz
You will need to copy over your own versions of malloc.c and free.c to extend for the current assignment.
Be certain to make clean before compiling for the first time.
This "clean slate" version of the system includes compiled versions of the solutions for previous assignments, but none of the .c source files. As an incentive, those who continue with their existing codebase are eligible for a 5-point bonus on the final exam score.
While the semaphores explored in a previous assignment do a decent job of allowing cooperating processes to communicate, many operating systems provide a more general mechanism for inter-process communication (IPC).
Build a simple message passing system for IPC between processes in your embedded operating system.
This can be accomplished in several steps.
Function send() takes a PID and a message, and sends it to the specified process. Function send() should perform error checking on the process ID, and check whether the destination process already has a message. If the destination process already has a message, send() should instead place the outgoing message in its own PCB's msgout field, enqueue itself on the destination process's msgqueue, and set its own state to PRSEND before yielding the processor.
Function sendnow() takes a PID and a message, and sends it to the specified process. Function sendnow() should perform error checking on the process ID, and should return a SYSERR if the intended destination already has a message waiting. If the intended destination process is already waiting for a message, sendnow() should unblock that process and yield the processor. Function sendnow() should not block.
Function recv() returns the message sent to the current process. If there is no message already, recv() should block, that is, put the current process into the PRRECV state and reschedule. If recv() sees other processes waiting to send in its msgqueue, it should dequeue the process, grab the message from that process's msgout field, and unblock that process before returning.
Function recvnow() returns the message sent to the current process. If there is no message already, recvnow() should not block, that is, it does not wait, and instead immediately returns a SYSERR.
The C programming language generally does not include a garbage collector, and instead relies on programmers to be meticulous about free()ing any dynamic memory they may have malloc()ed.
While a full-blown garbage collector requires tracking all possible references to a dynamically-allocated memory location, (which is notoriously intractable in C,) we can nevertheless implement a simple per-process collector that tracks every call of malloc() made by each process, and then automatically calls free() on any remaining blocks when a process is kill()ed.
Add a new field declaration to the PCB struct, memblk *myblocks, which is initialized to NULL in create().
Add code to malloc.c to add each new block from getmem() to the current process's myblocks list. (Hint: You can make another call to getmem() to make space for this new information; you can repurpose the length payload field of a memblk struct to keep track of the new block.
Add code to free.c to deregister a chunk from the process's myblocks list.
Add code kill.c to call freemem() on any remaining dynamically-allocated blocks in a process's PCB.
[Revised 2020 Mar 24 15:11 DWB]