Advice needed immediately

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Ozguxxx

Advice needed immediately

Post by Ozguxxx »

I am absolutely stuck at the beginning of multithreading stuff. ??? I need advice on how to approach starting of implementation of multithreading. Thanx...
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:Advice needed immediately

Post by distantvoices »

Multithreading is not that difficult:

at kernel level, each thread gets its own process structure, its own tss, BUT: The thread stays in the process memory area, it just gets its own data pages allocated. I think the thread should also get its own stack and heap, as if it were a real process.

As the thread is executed in the context of the process that has spawned it, it is easy for threads to pass data one to each other.

As you see, the kernel just sees processes, be they threads be they real processes. It is up to the job management to build the thread the right way.
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
Ozguxxx

Re:Advice needed immediately

Post by Ozguxxx »

Thanx for the response, I think I started learning it. (At least I hope. :) ) Anyway. I have another question. When task switching is being done, is TSS loaded by mpu or should it be done manually by switching software itself? Very specific question. Thanx...
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:Advice needed immediately

Post by distantvoices »

If you use hardware taskswitching, you might have multiple tss-selectors or just one (this is tricky - see john fines pages for how to do that), which you jump to at every task switch.

Task switches you do with interruptses and a quick scheduler code which manages the task queues and hands the task to be run to a small asm stub which prepares the stack for iret. This Means that you will have to include some calls in your interrupt asm stub: One to call the interrupt handler, one to call the scheduler and afterwards the above mentioned preparation before iret: because the return address for iret are the last two items on the stack (selector:offset) i think. I don't remember it clearly at the moment. If i am in error, pls let me know. In case the selector points to a tss, the offset is irrelevant. The processor performs the task switch upon iret to the new tss.

In software taskswitching, youhave to save all hardware registers manually (pushthem to the stackframe of the process?), load the stackframe of another process (handed over by the scheduler) and pop off the registers (EIP is there our great point of interrest: It is the instruction pointer) you prepare the stack for iret to jump to the position of EIP. upon iret, the last two items on the stackframe are (selector:EIP)

The tricky thing is always this preparation of the stack for iret, after interrupt is done, so that a new or just the same process is jumped to.

If this is wrong, pls let me know. I am human and thus prone to err.
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
Ozguxxx

Re:Advice needed immediately

Post by Ozguxxx »

Hi, I do not think I understand clearly what you mean by task switching via interrupts. Do you mean the task switching caused by gates in idt? If you mean this then I do not need them for moment. I am trying to implement very simple task switching based on tss loading stuff. My problem is: When you do a task switch by CALLing or JMPing to a task gate or to a tss descriptor, is old tss updated by mpu or not? Thanx...
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:Advice needed immediately

Post by distantvoices »

ad interrupts and task switch:

I mean: use the interupts to have the scheduler executed to decide which process to run next.

task gates: they can be located in the idt, i have read some where.

ad hardware taskswitches:

before the processor loads the new tss and starts the new process, it saves the old process' hardware state in the old tss as far as i know.

what is mpu?
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
Ozguxxx

Re:Advice needed immediately

Post by Ozguxxx »

I am sorry, mpu:micro processing unit - processor itself. :)
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Advice needed immediately

Post by Pype.Clicker »

never seen that "mpu" stuff ... "cpu" for "Central Processing unit" (pentium), "GPU" for "graphical Processing Unit" (Riva) and "fpu" for "Floating Point Unit" (yeah, that 80387 you cannot afford and which doubles the frame rate in Flight Simulator 2 :D )

Be aware that only *some fields* -- known as the dynamic fields -- of a TSS are written back at task switch. Among others, SS0, ESP0, LDTR and PDBR are not updated.

Here come a small document i wrote about my experience of multithreading... it might not help you as much as a real tutorial, but it could give you some hints nonetheless ...
Ozguxxx

Re:Advice needed immediately

Post by Ozguxxx »

So this means that we have to *manually* set up SS0, ESP0, LDTR and PDBR on a task switch, right. BTW, article is cool but I could understand only some beginning parts of it because I think it is api dependent and I dont know much about clickerOS. Thanx...
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:Advice needed immediately

Post by distantvoices »

You set them up upon setting up the task. initialization. There you build stack frame for the task, page directory and eventually an ldt - local descriptor table. I think these fields schall not be changed whilst the task is alive, because they stand for essential structures of it.
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
Ozguxxx

Re:Advice needed immediately

Post by Ozguxxx »

Ok, suppose I got task switching working. Now I am confused at some place: When task swtiching is done on a timer int based method, we certainly have to call task switching function inside timer handler.(right?) But when we call this function and when it passes control to another task, our timer handler does not return.(right?) So the isr for timer handler does not return as long as this task executes, so task switching function cannot be called again because the switched task does not return. Is there a way to get around this problem or am i heavily confused at somewhere? I think it will be better if someone can tell me a way to do a timer int based task switching. (I searched for old threads but I could not find anything that is useful to me.) Thanx...
Curufir

Re:Advice needed immediately

Post by Curufir »

I think you're confused here.

Anytime you load up the PIT and unmask the timer IRQ you will eventually receive an interrupt which then calls your timer handler (Which presumably calls the scheduler in some fashion).

All you're looking to do is:
  • Receive a timer IRQ indicating a process switch
  • Mask the timer IRQ
  • Save the state (Registers) of the current process
  • Load up the state (Registers) of the new process
  • Load up the timer with the correct quantum (Length of time before another process switch)
  • Unmask the timer IRQ
  • Return from the interrupt into the new process
Getting your OS to do all this is moderately easy, getting it to do all this efficiently is quite difficult.

Note this just describes a very simple exchange of processes, threads are handled similarily but there are quite a few differences, and a complete OS may want to store a lot more information than just a process' registers.

I understand the confusion because this is outside normal programming flow, but it is precisely this external interruptability that makes task switching possible.
Ozguxxx

Re:Advice needed immediately

Post by Ozguxxx »

Hi Curufir, thanks for response. It is helpful but I have some questions. Firstly, is it necessary to mask irq? Because in fact I am disabling ints inside timer handler. So I think it is not necessary to mask irq.(Or is it? :) ) Secondly, I got point of interruptiblity but my real problem is completely returning from interrupt handler so that I can reenable interrupts and wait for another task switch.(Is there a short code snippet that shows returning from irq handler and then switching to new task? I think my assembly knowledge is not enough.) Thanx...
Curufir

Re:Advice needed immediately

Post by Curufir »

Remember that you are replacing the stack(s) when you switch to a different process. It's your manipulation of the values that will be popped off this stack on iret/ret instructions that allow you to return execution to the new process.

Enable your interrupts before you return from the handler (There's no reason the process should know/care that it has been interrupted). Quanta are usually in the order of 10s of milliseconds whereas the interval between you loading the timer, enabling interrupts and returning to the process will mostly likley be under 1 millisecond. If an interrupt happens between the enable and the return to process it is incredibly unlikely that it is a process switch.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Advice needed immediately

Post by Pype.Clicker »

all you have to do to have your task switching correct is to send OUT 0x20,0x20 *before* you switch to the other task ...
Post Reply