Trying to wrap my head around processes

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.
Post Reply
raindog308
Posts: 3
Joined: Wed Aug 24, 2016 2:30 pm

Trying to wrap my head around processes

Post by raindog308 »

I've been fooling around with writing an OS, having read MikeOS, and also Nick Blundell's paper on how to write your own OS. I've also read (well, perused) various books on OS design and internals. But I'm struggling with the idea of processes, or rather their implementation.

I understand the concepts (at least, how they're typically implemented in Unix) but not how one might code an OS that can interrupt and schedule processes.

Let's say
  • we have a single-processor system to keep things simple. I want two processes to be running in a multiprogramming environment.
  • Obviously, only one process is truly executing at any given moment, but the OS can simulate switching back and forth so it appears to the user that both are running.
  • Let's leave out any process queue optimization, priorities, etc. and just say we're going to round-robin the processes with some arbitrary time for each to run.
So the OS loads one processes's instructions at memory location 100000. It loads the second process at memory location 200000.

The OS decides the program at 100000 should execute, so it JMPs there. It marches through the addresses: 1000001, 1000002, etc. Let's say it gets to 1001000 and the OS decides it's time to switch to the other process.

THAT is what I don't get. How is that done? The processor in my mind is sequentially moving through the addresses, jmping/adding/moving/etc. How can an OS (which is just another program) jump in and say "hold up, I'm going to freeze your register states and then switch to memory address 200000"?

If there was cooperative multitasking, I could understand a process "yielding" by having a JMP back to some location where task-switching opcodes execute. But this is preemptive.

It's almost like there needs to be a separate computer that runs "above" the regular computer to direct it. Are we into kernel protection rings here? But even there, I'm not seeing how that would work in assembler.

I'm sure there's a concept, paper, chapter, or book I'm missing...anyone point me at a breadcrumb trail? Thanks.
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: Trying to wrap my head around processes

Post by Gigasoft »

Remember, an interrupt handler may also cause a task switch. Just make sure that you keep track of when nested interrupts occur, so that you don't switch to another task until the outermost one is about to return.
User avatar
BrightLight
Member
Member
Posts: 901
Joined: Sat Dec 27, 2014 9:11 am
Location: Maadi, Cairo, Egypt
Contact:

Re: Trying to wrap my head around processes

Post by BrightLight »

For preemtive multitasking, you'll want to switch tasks when the process uses up its timeslice. For example, you can give each task 10 ms to execute, and use a timer such as PIT or HPET to keep track of the time. Aside from that, you can also switch tasks (really put the task in waiting/sleep state) when it waits for something to be done, for example, while waiting for a disk controller to spin up, or waiting for a network packet to be received, etc... This way, other tasks can execute while the waiting task "sleeps", saving even more performance.
So for preemtive multitasking, you should design it to work with system calls that take time-consuming operations such as a filesystem, as well as using timeslices.
You know your OS is advanced when you stop using the Intel programming guide as a reference.
raindog308
Posts: 3
Joined: Wed Aug 24, 2016 2:30 pm

Re: Trying to wrap my head around processes

Post by raindog308 »

Actually, I'm a level below you guys.

I should have searched the wiki...what I was looking for was a timer interrupt:

http://wiki.osdev.org/Multitasking_Systems
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Trying to wrap my head around processes

Post by Brendan »

Hi,
raindog308 wrote:The OS decides the program at 100000 should execute, so it JMPs there. It marches through the addresses: 1000001, 1000002, etc. Let's say it gets to 1001000 and the OS decides it's time to switch to the other process.

THAT is what I don't get. How is that done? The processor in my mind is sequentially moving through the addresses, jmping/adding/moving/etc. How can an OS (which is just another program) jump in and say "hold up, I'm going to freeze your register states and then switch to memory address 200000"?
It's better to think of it more like "the scheduler saves the previous task's state, then loads the next task's state". There's no actual "JMP".

Also note that if the currently running task blocks for any reason (e.g. does "sleep()" or has to wait for disk IO or has to wait for user to press a key or....) then you switch to a different task and do that instead; and when whatever a task is waiting for happens and the task is unblocked again it can start getting CPU time again. It's this blocking and unblocking that is responsible for the majority of task switches (and the timer is mostly only used for "task has run for too long without blocking"). If all tasks are blocked, then the scheduler has nothing for the CPU to do. There's 2 approaches to this - either make sure there's always at least one task the CPU can do (e.g. have an "idle thread"), or the scheduler waits for any task to be unblocked.

Finally; processes aren't executed, threads are. Without multi-threading a process has one thread, and with multi-threading a process has one or more threads. A process is like a container - it contains things like the process' virtual address space, file descriptors, and threads. A scheduler schedules threads and doesn't necessarily need to care which process those threads belong to. When a thread terminates, if it was the last thread (and the process has no threads left) then you terminate the process too.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Post Reply