| Friday, September 28, 2001 |
|---|
Question
Do ReceiveInterrupts block TransmitInterrupts from the same terminal?
Answer:
No, both ReceiveInterrupts and TransmitInterrupts can occur simultaneously.
Question
If I call DeviceInputSpeed(1,0) and then have rapid input, the following error is displayed:
Error: New character received but previous still unread! (tty 1)
Answer:
You're not expected to handle the case where the transmission time is 0.
Question
When the user program outputs to the terminal and the user types in characters, should both be written to the input buffer? For example: if writeTerminal is called on "abcd" and the user types "xyz" and the output to the terminal is "abxyzcd" should the input buffer contain "abxyzcd"?
Answer:
Any characters from user files outputted using writeTerminal should not be entered into the input buffer. So in this case the input buffer would contain "xyz".
Question
Are we allowed to use flags in semaphores? Or can we only use P and V to control threads?
Answer:
It is acceptable if you need to use global flags, just be careful that they don't circumvent your semaphores or create other concurrency issues.
Question
Should backspace characters inputted from the user delete characters outputted by user programs using writeTerminal?
Answer:
Backspaces entered by the user should be echoed to the screen just like any other character. If this ends up deleting user output, no problem.
Question
Should a file with SystemBoot() in it be submitted for project 2?
Answer:
While files with SystemBoot() in them will be useful to you for testing, we'll provide our own, so you don't need to turn yours in.
Question
When the echo buffer overflows, should the terminal drop characters until space is available and then output new characters as they come in, or wait until the current buffer is empty before accepting new characters?
Answer:
When the echo buffer fills, it should drop characters and beep until space is available and place the next character into the available space.
Question
Is it necessary to use condition variables to implement semaphores to ensure queuing?
Answer:
Yes condition variables should be used within your semaphores, it provides a simple way of queuing and blocking without spinning.
Question
If the buffer is filled by newlines, should a backspace be allowed to delete them?
Answer:
No, newlines should not be deleted.
Question
Is it valid to choose a 1:1 mapping where terminal=minor? Is it necessary?
Answer:
You can use the mapping if you wish, but it is not necessary.
Question
Is argument verification allowed before attempting to enter a monitor, or does this violate the monitor?
Answer:
Argument validation is allowed and encouraged, but to maintain the monitor place the validation in a wrapper around the entry function.
Question
In the specifications we are required to put the entire implemenation of the monitor in montty.o and semaphores in semtty.o. If we have code that is to be used by both implementations, how do we include it in both?
Answer:
If you have code you'd like to share, please compile it into a static library. To do this, compile the files into a static library. ie: ar rcs libmonitor.a montty.o buffers.o
Question
Will getpid() return a different pid on threads of the same process?
Answer:
getpid() will return the same number for every thread.
Question
Our code segfaults when echoing multiple characters because we wait for the transmit interrupt from within the receive interrupt handler. Is there a way to fix this?
Answer:
You should never block for unbounded amount of time within interrupt handlers. The untransmitted characters should be saved somewhere that the transmit interrupt can access them later.
Question
If one process is signaled and woken up and decides that it still can't run, should it signal before blocking again?
Answer:
Yes, there should be a signal before calling cond_wait, but if nothing else is waiting, this signal will be ignored, which may cause problems so be careful.
Question
If there is a backspace typed, should there be a beep heard at the beginning of a line or when the program knows the buffer is empty even if all of the characters have not been deleted on the display yet?
Answer:
There should be no beep if the buffer is empty, the backspace should delete the previous character on the screen. As for when the cursor is at the beginning of the line, that's your choice.
| Thursday, September 27, 2001 |
|---|
Question
Is there anything wrong with making the ReceiveInterrupt and TransmitInterrupt functions be entry functions into the monitor?
Answer:
No there is nothing wrong with this, as long as they do not block for any significant period of time (i.e. all they ever wait for is entry into the monitor).
Question
When "int sem_creat(sem_t *sem, int value)" is called can we assume that sem points to a sem_t struct that has already been allocated, or is this just a type and the variable has indetermined value or should we check to see if it is one of these and then proceed accordingly?
Answer:
Your code defines the type sem_t. Your sem_create receives a pointer to an object type sem_t. It is up to your sem_create() function to initialize the object. Thus the answer to this question is in your code, and may be implementation dependent.
Question
It says in the assignment to do a one-to-one mapping from terminal to minor numbers. How is this set up? The minors will always run from 0 to MAX_NUM_TERMINALS-1, correct? Do we just use the first MAX_NUM_TERMINALS calls to InitTermals to set up the terminal numbers? And then arbitrarily map these to minor numbers?
Answer:
Yes. Everything that you mentioned there is correct and is allowed.
Question
The Q/A says that there should be one monitor per terminal, the assignment says that there should be one mutex per monitor, this seems to imply that there should be a total of MAX_TTY mutexes that are instantiated. Should the code for the monitor be placed in a C file seperate from montty.c? Could you clarify "Entry function"?
Answer:
Think of a monitor as a C++ class - you can have multiple instances of that class. Think of your terminal driver as a monitor, and having a separate instance of a monitor for each terminal. Basically the way you descriminate between which monitor instance should be called when a particular method is invoked, use the terminal number parameter passed to that method to lock the correct mutex/use the correct local data associated with that particular instance. An entry function is a method for a monitor - basically, again equating this to C++, an entry function is a public function, whereas all other functions in a monitor are private and can not be called by anything outside of the monitor.
Question
Is WriteTerminal() not supposed to return until all the data it was called with has actually been printed?
Answer:
WriteTerminal() should return after all the characters associated with the WriteTerminal() have been printed on the terminal.
Question
On special character processing, we will need to replace one character with several characters and place them in our echo buffer (i.e. \r will be replaced with a \r\n). Should we use a policy where if we cannot fit all of the characters, beep and ignore the entire sequence, or is it safe to just fit what we can of the sequence and beep if anything is lost?
Answer:
For special characters you should never separate the multi-character sequence. I.e. if there is not enough space in the buffer for \r\n, then you should not place either one into the buffer.
Question
Will a ReceiveInterrupt block TransmitInterrupts?
Answer:
No, they can occur simultaneously.
| Wednesday, September 26, 2001 |
|---|
Question
The assignment says, and I quote,``The "Monitors version" of your assignment should use exactly one monitor.''
However, this seems to cause a lot of problems, and my partner seems to think you (Prof. Kesden) actually meant to use one monitor per terminal, based on a discussion he overheard you having with another student. This assignment is heavily graded on design, so I just wanted to be sure: is it one monitor for the entire terminal driver, or one monitor per terminal?
Answer:
You should have one instance of your monitor per terminal.
Question
There is a problem with the semaphore description as i see it. To initialize the mutex holding the monitor paradigm in the semaphore implementation there has to be an initializing function other than create_semaphore, since create semaphore is an entry function and must immediately acquire the mutex. If you are going to test our implementation without the terminal driver, than you have to call this init function or we need to be able to break the monitor paradigm to initialize the mutex. Im alittle confused here. Thanks.
Answer:
Unfortunately, there is an error in the assignment handout. Bothsem_create()andsem_destroy()are not entry functions into your semaphore monitor. As such, you are not required to acquire the monitor's mutex at the beginning of these functions and release it and the end.
Question
Do we need to implement backspace processing for WriteTerminal? i.e. is a legal write termal input "a\b"?
Answer:
If you receive a \b character in the buffer to your WriteTerminal(), please process the character exactly like every other character with a single exception -- when you go to actually write this character to the terminal, it expands out into the three atomic characters that are printed, uninterrupted, to the terminal.
Question
when "int sem_create (sem_t * sem, int value)" is called can we assume that sem points to a sem_t struct that has already be allocated, or is this just a type and the varible has indetermined value or should we check to see if it is one of these and then proceed accordingly.Basically what is the state of sem when this function is called.
Answer:
We expect to your code to work when called like so:... sem_t mysem; sem_create(&mysem); sem_P(mysem); ...In other words, you define the type sem_t. Your sem_create() receives a pointer to an object of type sem_t. It is up to your sem_create() function to initialize the object.A hint about how you should define sem_t: observe that the sem_P() and sem_V() functions take as input an object of type sem_t, not a pointer to an object of type sem_t. Also observe that these functions must change the state associated with the semaphore. What happens if you define sem_t to be some struct and call sem_P()? Will any changes you make to the struct persist after sem_P() has returned?
Tuesday, September 25, 2001 Question
When we set the input delay to average 0ms (and only 0ms), and hold down the input, sometimes we get the following (especially within WriteTerminal):Error: New character received but previous still unread! (tty 1) Abort
This occurs because the time between execution of the queued ReceiveInterrupts is sometimes too much. Is this acceptable behavior?
We've skimped our code about as much as we can without doing hacky optimizations.
Answer:
This is fine.Question
If for a ReadTerminal, the buflen is greater than our input buffer, should we report an error or just read as much as possible?Answer:
Read as much as possible, and return the number of characters actually read, so the value returned may be lower than the buflen passed.Question
Do we need to implement SynchronousMultiCast?Answer:
No you do not have to implement it.Question
Just had a quick question about ReadTerminal before we code this. Let's say my input buffer size is 100 bytes for now. Let's say the first reading thread comes in and has it's buflength set to 50 bytes. And say it ended up reading 60 bytes. So the amount we return to that thread is just 50 since this was it's buflength, the remaining 10 will go with the next read thread that comes in. But I just had a question about the amount the second thread can read. Can it read 39 more characters, or should it be able to wrap around the buffer until we reach the 51 array slot?Answer:
In your example, if you have two threads call ReadTerminal, both with buflength of 50, then each should return with 50 characters. [Whichever was called "first" should return the first 50] It can not "end up reading 60 bytes" because the buffer is only 50 - therefore it reads 50, and the rest of the characters remain in the 100 byte buffer to be read by the next ReadTerminal. as many characters as are available up until the first newline or bufsize(50) will be returned to the second ReadTerminal.
Sunday, September 24, 2001 Question:
Since we don't want to block within the interrupt handlers, does this mean that if we find characters to be coming in too fast, we should not process those characters at all?Answer:
The terminal driver should have a buffer between the InputDataRegister and the OutputDataRegister. This buffer should allow the terminal to function if, for a short period of time, a burst of input is faster than the output. Of course, over the long haul, the input rate cannot remain faster than the output rate -- the buffer will overflow.So, if the buffer becomes full, new characters shold be dropped. You should also produce a beep to let the user know what has happened.
Question:
For the WriteTerminal function, it says we need to give priority to the echo. So what should we do if WriteTerminal is using the output data register, and we try to type a character onto the screen. Are we supposed to somehow suspend that WriteTerminal thread? If so, how?Answer:
No. You cannot really stop the output of a single character after it has started. Instead, you should ensure that you never start outputting a character from a WriteTerminal(), if a character from echo is available.
Thursday, September 20, 2001 Question:
I assume we don't want either interrupt to call an entry function into the monitor, but I also assume that since the interrupts are not re-entrant, it is safe to mess with any data structures which will only be touched by those interrupt procedures (i.e. we get a mutex on them for "free")?Answer:
The Interrupt handers can enter the monitor -- no problem.
Question:
We think we want to block interrupts during our receive interrupt handler. How do you do this? Is it possible only to block certain types of interrupts? Or are we just looking at the problem wrong?Answer:
This is a very good idea. It is already done for you :-)
Question:
We want the receive interrupt handler to terminate as quickly as possible. Therefore, we don't want it to wait for the characters to be echoed to the screen. But using the monitor setup, I'm not sure how to ensure this. So, for example, I currently have an entry function: InsertIntoEchoBuffer(int term, char c) that puts the c into our write buffer with priority of echo. Our receive interrupt handler calls InsertIntoEchoBuffer. What I want to happen is for it to just dump the character into the buffer and initialize the process of echoing a character with the write register but not wait for it to finish (I guess not blocking on the transmit interrupt). Do you have any suggestions as to a good way to organize things to accomplish this might be?Answer:
As a first cut at a solution, why not keep a flag that indicates if a write is in progress. If a write is _not_ in progress, set the flag and dump it right into the register. If the flag is set, dump it into the buffer. Then, when a transmit interrupt occurs, it can check the buffer. If there is a acharacter in the buffer, it can deal with it. If not, it can set the flag to indicate that there is no pending write so that the next char can go right into the register (after setting the flag, of course).
Question:
Should things written to the terminal through writeterminal be placed in the readterminal buffer, or is user input the only valid readterminal buffer items?Answer:
If the readterminal buffer is the buffer that the ReadTerminal command gets its input from, then the answer is no, the WriteTerminal output should go to the user's terminal, and not into the buffer that the user may later read with ReadTerminal.
Question:
If you signal on the wait queue and there is nothing currently waiting, will the process that signaled just simply take back control with nothing else happening?Answer:
With Hoare monitors, a signal will wake up a waiting thread. If there are no threads waiting on the condition, then the signal goes unnoticed, and does not wake anyone up. although typically speaking, at least with Hoare monitors, you will want to signal at the end of your function, so it won't really matter...
Question:
Nothing should cause the interrupts to block, correct? So if the interrupt handler enters the monitor, any calls to the monitor from elsewhere should be very short lived?Answer:
Correct. It might be necessary for the interrupt handler to block very briefly. But, it shouldn't block for long. For example, the receive interrupt should never block while awaiting a transmit interrupt.
Wednesday, September 19, 2001 Question:
We know that 2 reads and 2 writes to the same minor at the same time can't happen, but can we have a read and a write occuring simultaneously to one minor? If so, do the characters from writeterminal get delivered to the readterminal? this would seem to require buffering the output of writeterminal which currently doesn't seem necessary.Answer:
Well, yes, and no. In theory, on a multiprocessor system, one thread could read at the same time another did a write. But, this would eventually be serialized by the memory controller, if no where else, and one fo them would be "first" and get into the monitor. At this point, one would go before the other and life will be grand. Similar logic should work for the semaphore approach.
Question:
When the ReceiveInterrupt handler gets a character and we need to output echo this character back to the terminal, are we allowed to block the call to ReceiveInterrupt until a TransmitInterrupt is received telling us the echo finished?Answer:
You can -- but this type of concurrency control should be using the same monitor or semphore approach at the rest of your solution.
Question:
In the monitor solution, although we can have only one mutex present, we can have multiple conditions right?Answer:
Absolutely.
Question:
We want to keep a global array of monitor structs, one for each terminal. The assignment says something about using fixed amounts of memory from the start. Should we statically allocate all the structs at the beginning, or should we have an array of pointers that are malloced as new terminals are opened?Answer:
It would be best to statically allocate these things. In general, we prefer that the kernel's memory be predictible and fixed-sized, whenever possible.