cs50300:fall16:lab4

DUE: Friday, October 7th by 11:59 PM

By the end of this lab students will be able to:

  • Understand how to create an infrastructure for event driven programming in an operating system.
  • Create a new system call to register for events.

Current operating systems, such as Android, have a mechanism for user programs (processes) to receive notifications from the operating system when various events occur. For example, in Android when the user “clicks” on the screen an event is generated and sent to the program by calling the onClick function.

Your job is to add a similar functionality to XINU by allowing a process to register a function pointer which will be called when events are signaled. Events can be signaled by either an arbitrary user process or the operating system itself.

To do this you will create two new systems call called regevent and sendevent. The format for regevent is as follows:

syscall	regevent(void (*event_handler)(uint32 event), uint32 event);

The system call registers an event handler (event_handler) with the operating system for a specified event. The event handler itself is a function with the following prototype:

void event_handler(uint32 event);

The function takes an argument that identifies the event being handled. The format for the sendevent system call is as follows:

syscall sendevent(pid32 pid, uint32 event);

NOTE: sendevent is similar to the send system call already implemented in XINU. However, instead of delivering a message to a process, sendevent causes the system to call the function that the process previously registered to handle the event.

In /homes/cs503/xinu there is a file called xinu-fall2016-lab4.tar.gz that contains a start to the code. Unpack:

tar zxvf /u/u3/cs503/xinu/xinu-fall2016-lab4.tar.gz

This will create a directory called xinu-fall2016-lab4.

Along with the main code for XINU, this tarball contains the following files (additional explanation of the contents of the files is in the following sections).

  • system/regevent.c - function declaration for the regevent function.
  • system/sendevent.c - function declaration for the sendevent function.
  • include/prototypes.h - modified prototypes.h file which includes the regevent and sendevent functions.
  • include/event.h - declaration of operating system and user events.

Your task is to complete these functions to perform the requirements specified in the previous section.

Contents of ''regevent.c''

The regevent.c file contains an empty function declaration for the regevent function. Your job is to fill in code to store the function pointer to be called when the event happens. If a process already has an event handler registered for a particular event, additional calls to regevent overwrites the exiting event handler for that event.

NOTE: the regevent system call only registers an event handler for a particular event (not all events). Consider creating an event table which records which processes have an event handler registered for each event.

Contents of ''sendevent.c''

The sendevent.c file contains an empty function declaration for the sendevent function. Your job is to fill in code to send an event to the particular process. If the target process identifier is not valid or does not have an event handler registered, the sendevent system call should return SYSERR. If the sender tries to send an operating system reserved event or some other invalid event, SYSERR should also be returned.

Contents of ''event.h''

The event.h file contains declarations for operating system events which you must implement. They are as follows:

  • PROCESS_GETMEM_EVENT - Sent when a process successfully allocates memory from the heap using getmem
    • NOTE: this event is only sent when the process SUCCESSFULLY allocates memory with getmem
    • If getmem fails, then the messages should not be sent.
  • PROCESS_FREEMEM_EVENT - Sent when a process successfully frees memory to the heap with freemem.
  • USER_EVENT_BOUNDARY - This is the lowest value that a user process can use for the event sent with sendevent.
    • All events lower than this value are reserved for use by the operating system.
    • If a caller of sendevent tries to send an event with a value less than USER_EVENT_BOUNDARY then SYSERR should be returned.
  • MAX_EVENTS - This is the maximum number of events the system can support. An event must be less than this value.

You will need to modify getmem.c and freemem.c in order to implement the OS events.

When to call an event function

NOTE: that at the time an event is sent, the process that has the event handler registered is not necessarily the current process that is executing on the CPU. So how do you get the event handler to run? For this lab, the registered event handling function needs to be invoked by the process which REGISTERED for the event, NOT the process which SENT the event.

Consider the situation where a process calls sendevent to send an event to a particular process. What process context is executing when the sendevent system call is executed? Think about how you would need to modify a process behavior to make this happen. HINT: Think about where in the XINU code the receiving process starts or continues to execute (i.e. look in resched.c). How can resched be modified to indicate that an event handler needs to be executed?

Multiple events and event ordering

Since the event handler(s) is/are not invoked by the Xinu until the process becomes ready to run in resched, it may be possible for a process to receive multiple different events or even the same event multiple times between the last time it was scheduled on the CPU. From a practical standpoint it might be beneficial for the operating system to queue sent events and call the event handlers in the order in which the events were received. For this lab you will not need to support queuing of events. The order in which the event handlers is called can be arbitrary.

How to handle processes with different priorities

Multiple processes (of differing priorities) can register an event handler for the same event and subsequently be sent the same event at approximately the same time. Consider the following situations:

  • Two processes (one with high priority and one with low priority) are sent an event. The low priority process is sent the event first. Should the event handler for the low priority process run before the event handler of the high priority process?
  • A process with high priority sends an event to a process with low priority - Should the event handler for the low priority process run immediately?
  • A process receives an event while executing within its allotted time quantum - Should the process be “interrupted” in order to execute the event handler immediately?

Other situations where event handler and process priority become a factor also exist. There are a couple ways you can implement the handling of these situations. For example,

  • Events can be handled at “high priority” – a process runs when it receives an event even if the process has low priority.
  • Events can handled at normal priority – a process that receives an event does not handle the event until the next time the scheduler selects the process for execution.

The choice of behavior is yours to make when implementing this lab. Make sure you document your decision and why you chose to implement the behavior as you did.

Event handlers and disabling/enabling interrupts

Since the event handlers are executed by the receiving process as soon as it becomes eligible to run, there maybe situations where interrupts are disabled when the event handler needs to be called. For example, suppose a process calls wait to wait on a semaphore and is queued in the wait state. While waiting, it is sent an event. This event is recorded for the process and should be executed when the process is no longer waiting. The semaphore is then signaled and the process is make ready to run. NOTE: at the time the process becomes ready to run, interrupts are still disabled since the process has not yet returned from the wait system call. If the event handler is invoked immediately, then the process will run the event handler with interrupts disabled.

Should event handlers always run with interrupts ENABLED? Since event handlers are functions provided by user process, for safety and fairness reasons it is desirable to have interrupts enabled when the event handlers execute. However, to provide such functionality in Xinu requires a significant effort such as needing an enable function that will enable interrupts and return a mask (essentially the opposite of the disable call) which can later be passed to restore. As such, you will not be required to handle enabling interrupts for this lab. In your lab analysis, discuss why running the event handler with interrupts enabled is the desired functionality.

Also note that event handlers may be executed with interrupts disabled when executing your test cases.

  • When a process terminates all registered event handlers must be removed.
    • NOTE: only the event handlers for the ending process should be removed.
  • A process can send an event to itself. For example, if a process registers a handler for event 12 with the call regevent(event_handler, 12); it can later send an event to itself with send event: sendevent(getpid(), 12);
    • This behavior should be allowed and the event handler should be invoked just as if another process tried send the event.
  • Make sure to remove all debug output from your system calls. When the TAs run your submitted code, calling a system call directly should not produce any output.
  • Provide a set of test cases to ensure that your code works as required. Put these test cases in main.c
    • Make sure your test cases not only test the new functionality of the new system calls, but that existing system calls still function correctly.
    • Don't forget to include test cases for the extra credit (see below) if you choose to implement the extra credit requirements. No extra credit will be awarded if test cases are not included.
  • The TAs will be replacing main.c with their own test cases after running your submitted test cases. Make sure you do not define any dependent variables in main.c. You are free to modify any other file(s) to implement the lab requirements.
    • Make sure that there are no dependent declarations in main.c.
  • If your submitted code does not compile (either the exact submitted code or the code after the TA's replace any test case files), you will receive zero (0) points for code execution. If this happens, you will be allowed to resubmit for half credit only.
  • Please run “make clean” prior to submission so that you don't submit object files
  • NOTE: When you make xinu for this lab the make file will generate a binary file in the compile directory called xinu. This is the file you will need to download to your backend.

Add another system call with the following prototype:

syscall broadcastevent(uint32 event);

Which sends an event to all processes that have an event handler registered for the input event. The order in which the event handlers are invoked is not important.

Submit using the turnin command (see below) your complete source code (all of XINU) including the any files you added to complete the lab. In the system directory include a PDF file called lab4_analysis.pdf with a report discussing:

  • The details behind your implementation. As part of this discussion write answers to the following questions:
    • Describe your test cases. How to they ensure that your code correctly meets the requirements?
    • This lab describes the use of several operating system generated events. Come up with four (4) additional operating system events that you think would make sense to also include in an operating system implementation of event registration (you do not need to implement these). Explain each event and why you think they would be useful.

NOTE: Make sure you put your name on your report, that the file is named exactly as specified, and the file located in the directory specified.

To turn in your lab use the following command

turnin -c cs503 -p lab4 xinu-fall2016-lab4

assuming xinu-fall2016-lab4 is the name of the directory containing your code.

If you wish to, you can verify your submission by typing the following command:

turnin -v -c cs503 -p lab4

Do not forget the -v above, as otherwise your earlier submission will be erased (it is overwritten by a blank submission).

Note that resubmitting overwrites any earlier submission and erases any record of the date/time of any such earlier submission.

We will check that the submission time stamp is before the due date; Any submission past the due date will be deducted the appropriate number of grace days. If submission is beyond your remaining number of grace days, your work will not be accepted.

  • cs50300/fall16/lab4.txt
  • Last modified: 2016/10/03 08:46
  • by lembkej