II) Operating System Structure

  -----------------------------------------------------------------------

                         pre-empted/interrupted
                         +-----------<--------+
                         |                    |
                         |                    |
             create      |     dispatch       |       kill
      [new] --------> [ready] ----------> [running] -------> [dead]
                         |                    |
         request granted |                    | kernel request/
                         |                    |  interrupted
                         +--<-- [blocked] <---+
 

                  Diagram 2.1 State transition of a process

  -----------------------------------------------------------------------
 
 

 

* System structure

A) Monolithic approach

  -----------------------------------------------------------------------
 
 
 
 
 
 
 
 
 
 
 
 
 
 

                 Diagram 2.2: Structure of a monolithic o/s

  -----------------------------------------------------------------------

  B) Layered approach (kernel approach)

  ------------------------------------------------------------------------
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

                    Diagram 2.3: Structure of an o/s kernel

  ------------------------------------------------------------------------
 

            +------------------------------------------+
            |              User Programs               |
            | +--------------------------------------+ |
            | |         Virtual i/o devices          | |
            | | +----------------------------------+ | |
            | | |     Virtual operator console     | | |
            | | | +------------------------------+ | | |
            | | | |   Virtual segmented memory   | | | |
            | | | | +--------------------------+ | | | |
            | | | | |Cpu allocation, semaphores| | | | |
           -+-+-+-+-+--------------------------+-+-+-+-+-                 +------------------------------+
      process   | Process creation/destruction |
     management |        +---------------------+--------+
      process   |        | Segment creation/destruction |
                |        +---------------------+        |
                | Process scheduling           |        | memory management
                +--------+---------------------+        |   process
                         | Segment management           |
                         +------------------------------+

* Process management

    CONST MAXPROCESS = N;
          MAXCPU = M;
          MAXPRIORITY = P;
 
    TYPE  CpuState = (executing, idle);
          ProcessState = (ready, running, blocked, dead);
          ProcessPriority = [0..MAXPRIORITY];
          ProcessId = [0..MAXPROCESS];
          Context = (* for the Cpu and PD *)
            RECORD
              pc : Register;  (* program counter *)
              sp : Register;  (* stack pointer *)
              cs : Register;  (* code segment pointer *)
              ds : Register;  (* data segment pointer *)
              (* and many other registers *)
            END;
 
          Process = POINTER TO PD;
          PD = (* Process descriptor *)
            RECORD
              name     : ARRAY OF CHAR;
              pid      : ProcessId;
              state    : ProcessState;
              processor: Cpu;
              env      : Context;        (* the volatile environment *)
              priority : ProcessPriority;
              next     : Process;
              (* and other bookkeeping information *)
            END;
 
          Cpu = POINTER TO CpuDescriptor;
          CpuDescriptor =
            RECORD
              state : CpuState;
              env   : Context;        (* cpu's physical context *)
              active: Process;        (* the current running process *)
              next  : Cpu;            (* to next cpu *)
            END;

    VAR   DeadPool : Process;  (* set of unused PDs *)
          IdleCpu  : Cpu;

    VAR   ReadyQueue : Process;
 

             Process A                        Process B
                 |                                |
         running |                                | blocked on a signal
                 |      resume process B          | from C
interrupt from C +------------------------------->+
                 | (save the volatile env. of A)  |
           ready | (restore the "      "   of B)  | running
                 |                                |
                 |      "Context-switching"       |
                 |                                |
                 |      resume process A          |
                 +<-------------------------------+ system call
         running | (save the volatile env. of B)  |
                 | (restore the  "     "   of A)  | blocked on the
                 |                                | completion of the
                 |                                | system request


      (* Dispatch the process 'p' to the processor 'c'. 'p' should be
         selected from the set of ready processes. *)
    PROCEDURE Dispatch( p : Process; c : Cpu );
    BEGIN
        IF c^.state = executing THEN
              (* preempt the running process *)
            Interrupt(c);   (* interrupt the processor c *)
              (* save the current active process's context *)
            c^.active^.env := c^.env;
            c^.active^.processor := NIL;
              (* put the current active process back into the ready queue *)
            QInsert(c^.active,ReadyQueue);
        END;
          (* processor c is now idle *)
        p^.state := running;
        p^.processor := c;
        c^.state := executing;
        c^.active := p;     (* p becomes the current running process *)
          (* load/restore the context of p *)
        c^.env := p^.env;
          (* resume the execution of processor c *)
        Start(c);
    END Dispatch;
 
 

          (* A process of name is created with priority n and its pid is
             returned. *)
        PROCEDURE Create( name   : ARRAY OF CHAR;
                          n      : ProcessPriority;
                          VAR id : ProcessId );
            VAR p : Process;
        BEGIN
            QDelete(p,DeadPool);
            p^.pid := NewPid();
            p^.name := name;
            id := p^.pid;
            p^.priority := n;
              (* Allocate enough memory for this new process,
                 load its code into the allocated memory, and
                 then initialize its stack and data areas.
                 Setup the process's new context pd(p).env.
                 Finally, put the new process into the ready queue *)
            QInsert( p, ReadyQueue );
        END Create;

        PROCEDURE Destroy( id : ProcessId );
            VAR p : Process;
        BEGIN
            p := PDof(id);    (* locate its process descriptor *)
            Stop(p);
            p^.state := dead;
              (* Deallocate all resources held by this process and
                 then put its pd back to the deal pool *)
            QInsert(p,DeadPool)
        END Destroy;

        PROCEDURE Stop( p : Process );
        BEGIN
            IF p^.state = running THEN   (* stop it! *)
                Interrupt(p^.processor);
                p^.processor^.state := idle;
                QInsert(p^.processor,IdleCpu);
                  (* save the process's context *)
                p^.env := p^.processor^.env;
            END;
        END Stop;
 

        PROCEDURE Suspend( id : ProcessId );
            VAR p : Process;
        BEGIN
            p := PdOf(id);
            Stop(p);
            p^.state := blocked;
        END Suspend;
        PROCEDURE Resume( id : ProcessId );
            VAR p : Process;
        BEGIN
            p := PDOf(id);
            IF p^.state = blocked THEN
                p^.state = ready;
                QInsert(p,ReadyQueue);
            END;
        END Resume;