System Information

Back to Index

Multitasking

Multitasking is one of the super-special things about BAOS, but aslo one of the most complicated things the OS does. What actually happends is the following:

  1. Inside the Timer Interrupt Table there is a repeating timer for multitasking. The Initial Counter Value of this timer is MULTITASK_TIMER, again declared in the BAOS headers.
  2. When this timer is triggered the system will make a call to nextproc_IR, which is a special place inside the nextproc function.
  3. Inside this function, inside this function, the system will PUSH all the registers (except the shadow registers) inside the program's stack (instead of TIOS, with BAOS every program has it's own stack, which is somewhere inside the memory).
  4. Now the system will take a look at the curproc variable (declared in the BAOS headers), this is the PID ("Process IDentity", an integer) of the process that is currently running.
  5. Next it will take a look at the multitasking table. A vector to this table is stored in the variable proctab.
  6. It does a lookup in this table for the current process (by it's PID).
  7. Now it puts the Stack Pointer into this table. With this stack pointer a lot of this are saved at once:
  8. It goes to the next entry in this table (the first one if the last one is exceeded) that is filled with a not-sleeping process.
  9. It loads this process' stack-pointer.
  10. It returns to the place where this program was interrupted.

NOTE: A program can also switch to the next process in this table by calling the nextproc function. This has however one side affect. In contrary to what some people may think, the next process will hev less execution time. This is because the multitasking system will switch to the next after a fixed amount of time, however a bit of this time is already consumed by the process that called nextproc, so after process-switching the amount of time it has is less then under normal circumstances.

NOTE2: There is one exception on the note above. This is when the timer-interrupt is actually trigered while the process-switching routine is being executed. Because you never want to let such a thing happen (switching while switching, this would mean that the process-switching routine data would be put into the process table and may result in a system crash) interrupts are being disabled while doing a precess-switch. Becouse of this the next process would have a little bit more execution time (since the process-switching was already done before the timer was triggered.

It's not sure what layout the process table will have at the end, but currently it has the following layout:

Byte 0 1 2 - 3 4 - 15
Description PID Running / Sleeping Stack Pointer Process Name
PID The Process IDentifier, an unique number (1-255) that identifies the process for the system.
Running / Sleeping This is the state of a process. Under normal circumstanced, a process is running (1), but if a process is sleeping (0), the system will never switch to it, which can be usefull together with timers or software-triggers.
Stack Pointer When switching processes, the Stack Pointer Register (SP) is loaded from or stored into here.
Process Name A process can give itself a name (most of the time the system will do this when starting a program, however a program may change it to anything) by calling the setprocname function. As long as the name (including the trailing zero-byte) is not longer than 12 bytes.

Starting and Stopping Processes

You can start a process by calling the newproc function. However most of the time you will probably starting programs instead of processes. Starting programs also includes loading a program into the memory, parsing memory locations, etc.

When the newproc function is called, the following things happen:

  1. First of all, the system searches for a free PID.
  2. Second, the system allocated memory for the program stack of the new process.
  3. The system puts the endproc function into the stack of the new program. This is done because when the program ends, it's entry inside to process-table should be destroyed and all (possible) not-freed memory should be freed by the system. All this is done by endproc.
  4. Then, dummy values for the registers will be pushed into the new program's stack.
  5. Everything will be stored into the process table.
  6. All changes to the stack, PID and other data of the parent-process are reversed and we will return to where we were called.

Stopping processes can be done in three different ways:

NOTE: in the last 2 ways of stopping a process, endproc will clean up all the mess the process leaves when "dissapearing", such as freeing memory.