Discussion:
Enabling interrupts for new processes
(too old to reply)
Timothy Finley
2005-03-07 20:18:19 UTC
Permalink
Although I practically have the necessary functionality for the project, I
realized that things didn't seem quite right. When running schedtest.ex
(why is just .ex and not a full .exe?) the processes would never
interleave. The printout of 1s and 2s would never be mixed together. After
doing some debugging I've figured out that I never actually was receiving
any timer interrupts while a process was running because interrupts were
never reenabled for user processes. With this I would never get any
timeslicing preemption.

I would assume that the project2 solution does this correctly (enabling
interrupts for newly scheduled user processes) so maybe I should take a
look at that. In Setup_Kernel_Thread the address of Launch_Thread is
pushed onto the stack (that function will enable interrupts) but we were
not indicated to do this in Setup_User_Thread for project2.

Hope this helps any of you who were using your own project2 and not the
given solution.

Tim
c***@CSIC.UMD.EDU
2005-03-08 22:21:38 UTC
Permalink
are you saying we need to Enable_Interrupts() in Setup_User_Thread? i'm actually
having the same problem you stated but am slightly confused as to your solution.
Timothy Finley
2005-03-08 23:21:58 UTC
Permalink
Post by c***@CSIC.UMD.EDU
are you saying we need to Enable_Interrupts() in Setup_User_Thread? i'm
actually having the same problem you stated but am slightly confused as
to your solution.
Well I haven't figured out a solution yet. After looking at the project2
solution code I see that it doesn't activate interrupts for user threads
either (or at least it doesn't seem to be), so I think everyone will have
this problem.

The problem is not when a thread starts, but when a thread is scheduled.
The very last step in thread scheduling is Switch_To_Thread(). We cannot
enable interrupts before then since the function Switch_To_Thread in
lowlevel.asm explictly tells us not to have interrupts enabled.

; Switch_To_Thread()
; Save context of currently executing thread, and activate ; the
thread whose context object is passed as a parameter. ; ; Parameter: ;
- ptr to Kernel_Thread whose state should be restored and made
active ;
; Notes:
; Called with interrupts disabled.
; This must be kept up to date with definition of Kernel_Thread ;
struct, in kthread.h.

So since this is the last function to be called before a thread is started
(it happens in the end of Schedule() in kthread.c) we must find another
means to get threads to schedule with interrupts.

I've tried a few things without success yet. My only guesses now are to
edit lowlevel.asm to enable interrupts inside the Switch_To_Thread method
(I don't think we're supposed to do this) or is to somehow get the user
thread to call a function which enables interrupts itself.

The interesting thing is that if you look at Setup_Kernel_Thread (what we
were supposed to model Setup_User_Thread on), you will see that the
address of the function LaunchThread() is pushed to the stack. That
function will enable interrupts (in fact LaunchThread() only has one line
of code; the Enable_Interrupts() call). So this allows the thread itself
to enable interrupts.

Unfortunately I don't think we can do this same exact thing for
Setup_User_Thread since the LaunchThread() address is in kernel space, not
user address space. I think this method would only work for user threads
if there is a way to push the Kernel code segment selector on the stack,
push LaunchThread on the stack, and then push the user code segment
selector and user starting address (but I would have no idea of how to do
this).

So right now I think that this a problem that we were not expected to run
into (but I could be very wrong). Soo... help, Iulian?

Tim

ps: One way to demonstrate this problem is to add a print statement to
Timer_Interrupt_Handler (timer.c). Note: This will really pollute the
console output (since it happens many times a second) so when you type in
the shell you will not be able to see what you type. It also helps to make
the length of the loops in user/sched1.c and user/sched2.c longer. Start
up bochs and type in '/c/schedtest.ex mlf 5' to the shell. Among all the
timer interrupt prints you should eventually see the printout of 1111 or
2222. For me when the 1s start printing I stop getting any of the timer
interrupt debug prints. Since I've made the 1s print very slowly (like 1
sec for each one) the timer interrupt should happen if interrupts are
enabled (since the timer interrupt happens many times per second), but the
debug prints don't happen indicating that I don't have interrupts enabled.

Sry for the long-windedness I've been thinking about this for a while.
Iulian Neamtiu
2005-03-09 16:17:14 UTC
Permalink
Check the third parameter that you push on the stack in
Setup_User_Process(). It's the eflags = CPU flags, and should be

Push(EFLAGS_IF)

and not

Push(0).

If you Push(0) you disable interrupts forever, and that was probably
causing you problems.


Note that the Project 2 solution does a Push(EFLAGS_IF) so it is correct.

Iulian
Post by Timothy Finley
Although I practically have the necessary functionality for the project, I
realized that things didn't seem quite right. When running schedtest.ex
(why is just .ex and not a full .exe?) the processes would never
interleave. The printout of 1s and 2s would never be mixed together. After
doing some debugging I've figured out that I never actually was receiving
any timer interrupts while a process was running because interrupts were
never reenabled for user processes. With this I would never get any
timeslicing preemption.
I would assume that the project2 solution does this correctly (enabling
interrupts for newly scheduled user processes) so maybe I should take a
look at that. In Setup_Kernel_Thread the address of Launch_Thread is
pushed onto the stack (that function will enable interrupts) but we were
not indicated to do this in Setup_User_Thread for project2.
Hope this helps any of you who were using your own project2 and not the
given solution.
Tim
Timothy Finley
2005-03-09 16:19:23 UTC
Permalink
The problem was that I was not setting eflags correctly in
Setup_User_Thread. Look how the project2 solution sets up eflags and do
that. I guess thats what I get for being stubborn to use my own project2.

Thanks Iulian!

Tim

Loading...