XML

kent logo

CO527 Anonymous Questions and Answers

This page lists the various questions and answers. To submit a question, use the anonymous questions page. You may find the keyword index and/or top-level index useful for locating past questions and answers.

We have taken the liberty of making some minor typographical corrections to some of the questions as originally put. Although most of the questions here will have been submitted anonymously, this page also serves to answer some questions of general interest to those on the course.


Question 41:

How do we signal the process with SIGPIPE ? The only way I can see is just to ``return SIGPIPE;'' but then the method would have ended and we still need to send the appropriate error to the process too.

Answer 41:

Use:

    MKernel.queue_signal(MProcess p, MSignal signal) 

Where `p' is the process that you want to signal and `signal' is the actual signal. The `MSignal' class has a constructor that you can use to populate the `signal-data', e.g. ``new MSignal (MSignal.SIGPIPE, null);''.

Keywords: moss , signal


Question 42:

What kind of messages are sent in by processes using the mailbox method ?

Answer 42:

See the answer to Question 10 (2003).

Keywords: moss , mailbox


Question 43:

In (1c) you said I should initialise the private state of `MSemaphore' but what should it be initialised to ? In the `Semaphore' class it gets initialised to 1 so would I want to set the `value' in `Sema4' to 1 ... or do I want to initialse to what values get passed through the semop if the `op' value is for creating?

Answer 43:

A newly created semaphore should be initialised to the `value' given. See the answers to Question 15 (2003) and Question 20 (2003).

Keywords: moss , semaphore


Question 44:

I really dont get what I am meant to be doing. I have started the mailbox and have created a `sendmsg()' method which creates a new `MailMessage' then adds it to an `ArrayList'; and a `receive()' message which iterates and finds a message in the `ArrayList' with the same PID but I have no idea what I am meant to be doing next, or if what I have done is even right.

Answer 44:

By the sound of it, what you have done so far is correct. Mailbox test-programs can be downloaded from the MOSS web-page. If you look over the source code for those test programs, you'll see how the `MPosixIf' `sendmsg()' and `recvmsg()' calls are used by applications -- your implementation should behave in a compatible manner. One thing, however, is that the test program will not complete successfully if the `recvmsg()' method does not block when no messages are available. From the assignment description: ``You should ensure that `recvmsg' blocks if no messages are available''.

Keywords: moss , mailbox

Referrers: Question 46 (2003) , Question 46 (2003)


Question 45:

Is there a method that given the PID returns the corresponding process associated with it?

Answer 45:

In the version of MOSS that you have, no, there isn't. A newer (ish) version of MOSS provides the following method in `MKernel' (you can copy this and stick it in your `MKernel.java' file, if you really need it..):

    //{{{  public static MProcess find_process (int pid)
    /**
     * finds a process from its PID
     *
     * @param pid PID of process to search for
     *
     * @return MProcess reference on success, or null if not found
     */
    public static MProcess find_process (int pid)
    {
        MProcess tmp;

        lock.claim_read ();
        for (tmp=task_list; tmp != null; tmp = tmp.next_task) {
            if (tmp.pid == pid) {
                break;          /* from for() */
            }
        }
        lock.release_read ();
            
        return tmp;
    }
    //}}}

Keywords: moss


Question 46:

I've just cracked the `mail-box' implementation, and have managed to get your test reciever class to receive all 4 messages sent to it by the test sender. However it does not finish and shows the following lines:

    child exited with code 0
    MOSS# UMailSend: done.  exiting.
    MInitTask::signal(17) SIGCHLD (pid=8, status=0)

In Question 44 (2003) you said if the `recvmsg()' method succesfully blocked then the test classes you made would not finish. Did I read this right and does that therefore mean that my `MMailBox' implementation is working correctly, or does the lack of the last 3 lines point to some yet unfound error?

Answer 46:

Firstly, I made a typo in the answer to Question 44 (2003) -- ``if your `recvmsg()' method does not block when no messages are available, things will go wrong.''.

If your program really generates the three lines above, then it's working fine! The first line of output is the `UMailRecv' process finishing, at which point the `UConsole' process wakes up and re-displays the ``MOSS# '' prompt. Shortly afterwards, the `UMailSend' test program also terminates. However, since that process's parent has died, the init-task gets the SIGCHLD message (and prints it out), which accounts for the last line out output.

You can check what processes are running/sleeping with ``run UProcList''. After the mailbox test has completed, you shouldn't see either `UMailRecv' or `UMailSend' in that list.

Keywords: moss , mailbox


Question 47:

What `int' is returned from:

    public static int sendmsg (int pid, int type, Object message)

in the `MPosixIf' ?

Answer 47:

This has already been answered; see the answer to Question 17 (2003).

Keywords: moss , mailbox


Question 48:

Hi, I have read your answers to get the PID of the invoking process and so have added the code:

    MProcess current = MKernel.current[MProcessor.currentCPU()];

    int processPID = current.pid;

to `MPosixIf' and then have the code:

    mail.from_pid = MPosixIf.processPID;

in `MMailBox', but I'm getting the error: ``cannot be referenced from a static context''. I don't know exactly which PID is supposed to be passed as a parameter to the methods in `MMailBox' ?

Answer 48:

The error is because you're trying to access a field `processPID' in `MPosixIf', that should not even exist, let alone be static/non-static.

If you need to transfer information between `MPosixIf' and `MMailBox' (such as the invoking process's PID), do it with parameters; not by adding fields to classes. You can't meaningfully add a `PID' field to `MPosixIf' anyway.. Thus, in your `MMailBox' implementation, the method header for, say, `sendmsg()', you should add the extra (invoking/sending PID) parameter:

    public static int my_send_message (int src_pid, int dst_pid, int type, Object message);

and when you call that from `MPosixIf' (with ``MMailBox.my_send_message (...)''), pass the extra argument (`processPID') there.

Keywords: moss , process-id


Question 49:

In (1c) when doing `SEMOP_SET' I'm baffled as how to find the `Sema4' with the same key so can change its value... I'm probably using the class all wrong, I really don't know...

Answer 49:

The `Sema4' class holds information about a single semaphore. The `MSemaphore' should hold all of these -- probably using a collection class, such as an `ArrayList' (or even a `Hashtable', since the semaphore `key' is unique). Once you've got a collection, it can simply be searched for a matching `key'; that will give you the relevant `Sema4' object.

You could also do this by adding a ``Sema4 next'' field/attribute to the `Sema4' class, and managing them as a linked-list (presumably sorted). Or even as a binary-tree using ``Sema4 left, right'' fields.

Keywords: moss , semaphore


Question 50:

Where do we get the test for the `mailbox' (1b) option from ? I have downloaded the package and have completed my implementation but am unable to test it as the `UMailRecv' is not in the package. Any help please?

Answer 50:

You can download the `UMailRecv and UMailSend' sources from the MOSS web-page. They're in the ``Download'' section (as .zip or .tar.gz). Instructions for compiling them are there too (essentially, ``javac UMail*.java'', add to the Makefile and/or the Bluej project).

Keywords: moss , mailbox


Question 51:

When a process is blocked is it just simply added to the `MWaitQueue' in the `MPosixIf' class ?

Answer 51:

You should word your questions more carefully! The submitted one referred to `MSposfix'; I assume you meant `MPosixIf'.

There shouldn't be any `MWaitQueue's in anything you add to `MPosixIf'. Processes should block in the implementation-specific file you write. For a description of how process blocking is done, see the answer to Question 18 (2003).

Keywords: moss


Question 52:

What should be returned if `recvmsg' is interrupted by a signal, if anything ? I noticed in `MPipe' an `int' is returned to indicate it, but `recvmsg' returns an object.

Answer 52:

You should just return `null'. This means, of course, that the user-process can't distinguish between a `wait' that was interrupted and other errors. But that's fine, for now.

The reason I decided to make it return the message `Object', instead of an `int' indicating success/failure, is because collecting the message in the latter case becomes messy. We want to return two things from this method, and Java doesn't make this easy..

Neither of these are particularly pleasant..

Keywords: moss , mailbox , signal

Referrers: Question 97 (2003)


Question 53:

Are there any other tests we can use for the `pipe' (1a) ?

`UPipeTest' works, but does this test that the end-of-file and SIGPIPE conditions are working properly ?

Answer 53:

No, there are not any additional pipe tests. The existing `UPipeTest' does not test for end-of-file/SIGPIPE either. However, modifying these to incorporate such testing should not be too difficult.

Testing for end-of-file is easy: modify the `UPipeTest2' program such that it does an extra read. For example:

    x = MPosixIf.read (fd, buffer, buffer.length);
    if (x < 0) {
        // report error
    } else if (x != 0) {
        // another error, we were expecting end-of-file (zero)
    }

Testing for SIGPIPE is slightly harder. The writer needs to make sure that the reading process has terminated before attempting a second `write'. You can do this (crudely) by modifying `UPipeTest' to include a short delay before the second write (which should cause SIGPIPE to be delivered). You'll also need to setup the signal-handling for SIGPIPE. For example:

    MPosixIf.signal (MSignal.SIGPIPE, MSignal.SIG_CATCH);
    MPosixIf.sleep (1000);          // sleep for 1 second (may be less
                                    // if SIGCHLD arrives whilst we're sleeping)
    x = MPosixIf.writestring (fds[1], "This should cause an error :)");
    if (x < 0) {
        // check to see what the error was, should be EPIPE (if that's what you return)
    } else {
        // something else wrong
    }

Keywords: moss , pipe

Referrers: Question 109 (2003)


Question 54:

When I call the `sendmsg()' and `recvmsg()' methods in `MMailBox' I get null-pointer exceptions. I have an `ArrayList' field but I can't initialise it using a constructor because it is `static'. If I were to call ``new ArrayList' in each `send' and `recv' method call I think this would be wrong.

I'm not sure how to go about this or if I am even on the right lines.

Answer 54:

Yes, you do need to initialise this somehow. There are three sensible ways. The first is the simplest, but is not so desirable. The third would be the most ideal, but involves more coding.

  1. Initialise it directly:

        private static ArrayList the_messages = new ArrayList();
    
  2. Test at the start of the `send' and `receive' methods, and initialise if needed.

  3. Add a new method, e.g. `init_mailbox()', that performs the initialisation:

        public static void init_mailbox ()
        {
            the_messages = new ArrayList ();
            // any other initialisations
        }
    

    Then call this method from the kernel startup code in `MKernel.init_kernel()' -- just add the mailbox initialisation call to the end of the method, e.g.:

        MMailBox.init_mailbox ();
    

Keywords: moss , mailbox , initialisation

Referrers: Question 84 (2003)


Question 55:

I've been writing a file device-driver for file operations. I've been understanding the majority of how to get this working through various texts, but I'm still baffled about how to get the actual file I want to read into the device-driver. I'm guessing this would be from a path to the file, but I can't work out how this would be given to the device-driver.

Answer 55:

Hard-coding a file-name (e.g. a `private static final String' field/attribute) is one option, but it isn't terribly nice. The way to handle initialisation for this sort of thing, currently, is to add a specific method to `MPosixIf', that calls some suitable method in your device-driver. That way, the application can get hold of a file-descriptor and do the initialisation of the driver all in one go. Until MOSS gets a functional file-system (and better device-driver management), this is more or less the only sensible way to do this type of initialisation.

Keywords: moss , device-driver , initialisation


Question 56:

I can't get the `UMailRecv' test class to work - basically my `MWaitQueue' never gets filled with any objects. I can see a bit in the `UMailRecv' code which is meant to create a fork and call `UMailSend' but for some reason it doesn't ever get to the `UMailSend' code. This is the output I get:

MOSS# run UMailRecv
process started, PID 3
UMailRecv -- mail-box receiver process
UMailRecv: started message sender, pid 4
UMailRecv: MPosixIf.recvmsg() returned null! -- retry..
    ...
UMailRecv: giving up..
UMailRecv: MPosixIf.recvmsg() returned null! -- retry..
    ...

Any ideas ?

Answer 56:

This is happening because your `recvmsg()' method isn't blocking when there are no messages available -- as you've identified by not having any objects (processes) in the `MWaitQueue'.

The sending process is started, but never gets the chance to run.. MOSS is not a pre-emptive operating-system; processes must voluntarily give-up the CPU (by sleeping). You can `yield' the processor by having the `UMailRecv' program call ``MPosixIf.reschedule ()'' before it starts to receive messages. Alternatively you could insert a delay using ``MPosixIf.sleep (500)'', that would sleep for approximatly half a second (500ms).

To actually fix the problem, you'll need to find and cure the bug in your `recvmsg()' code.

Keywords: moss , mailbox


Question 57:

Sorry but ignore the last post on the `MWaitQueue' not filling up - just a silly bug (using > rather than <). However, now my code runs and I think it's ok but the output is not quite the same as yours:

    ...
    UMailRecv: got message [Hello, mailbox world 0 :)]
    UMailRecv: got message [Hello, mailbox world 1 :)]
    UMailSend: done.  exiting.
    UMailRecv: got message [Hello, mailbox world 2 :)]
    UMailRecv: got message [Hello, mailbox world 3 :)]
    child exited with code 0

The ``UMailSend done. exiting.'' line should appear at the end I think - but I do recieve all the messages, so is this still ok?

Answer 57:

I've already answered the previous question.. but it added some useful stuff about MOSS pre-emption.

That output is fine -- see the answer to Question 24 (2003). It happens because the `UMailSend' process terminates first. The scheduling order of processes should be considered non-deterministic (like an occam `ALT'). On my Linux box, `UMailRecv' generally finishes first; there are a lot of factors which affect this, however.

Keywords: moss


Question 58:

I am just trying to revise the efficiency of my code and wonder if you can give me some advice.

At present, my `recvmsg' method in `MMailBox' uses a series of `if' statements:

    if (bad parameters) {
        ...
    } else if (parameter_x == -1) {
        ...
    } else if (parameter_y == -1) {
        ...
    }

At the moment, each of these `if's contains a seperate mechanism to scan the message-store, and return an appropriate value if neccessary. Do you think it would be better for me to have a single scanning mechanism (i.e. a loop) and make all the checks on each `MailMessage' object in one scan ?

Further to this point, assuming that the message-store is an `ArrayList', would it be better to use the `get()' method for each check made on a `MailMessage', or to call the `get()' method once, and assign the `MailMessage' to a local variable which can then be used to make the neccessary checks. i.e:

    message-store.get(1).var1 == param1 
    message-store.get(1).var2 == param2
    message-store.get(1).var3 == param3

or:

    MailMessage message = message-store.get(1)
    message.var1 == param1
    message.var2 == param2
    message.var3 == param3

Thanks

Answer 58:

In response to your first point, yes, it would be better to have the loop once, and the checks inside. Even though this is slightly less efficient than having the `if' at the outermost level, is greatly simplifies the code. Both methods result in O(n) time, just one slightly more than the other. The increased readability/maintainability of code, in this case, outweighs the small loss in efficiency, in my opinion anyway. This sort of decision making often depends on the nature of the software, though.

On your second point, the latter method is definitely better -- i.e. doing the `get()' once then using something local. This is definitely more efficient (in terms of the code that the compiler generates), both in time and space. The code is also generally `better' (looks nicer and is easier to maintain).

Keywords: moss , efficiency


Question 59:

For the `mailbox' (1b) option of the assignment, do we need to deal with signals like `MPipe' implementation does ? Or is that specific to `MPipe' ?

Answer 59:

For the mailbox, you do not need to worry too much about signalling (in the sense that no signals are generated as the result of `sendmsg()' or `recvmsg()' code). Some small consideration of signals would be good, however. For example, when a process returns from `MKernel.schedule()', it either did so because you woke it up, or because it was woken as the result of being signalled. See the answer to Question 18 (2003) for an idea of how this should be handled.

Another useful signal-related thing would be to call `MProcess.sync_process_signals ()' in `MPosixIf' -- look at the other methods in `MPosixIf' for an idea of how this is used.

Keywords: moss , mailbox , signal


Question 60:

Can we not simply make a call to `getpid()' in `MPosixIf' to get the current process id ?

Answer 60:

You can, but it's not as efficient as doing it directly. All `getpid()' does is:

    MProcess current = MKernel.current[MProcessor.currentCPU()];
    return current.pid;

If you already have the `current' process in a local variable, it's arguably simpler just to access it's `.pid' field/attribute, rather than calling `getpid()'.

Keywords: moss , process-id

Valid CSS!

Valid XHTML 1.0!

Maintained by Fred Barnes, last modified Thu May 8 12:58:05 2014