In XINU, the process control block (PCB) is used as the location to save process state in order that a process may be restarted after being switched out during a context switch. Because this is where state is saved, it is useful here to look at the contents of the PCB before we look at the act of context switching. If you remember the contents of the Pthreads PCB, you will find that the XINU PCB is not all that different.
XINU PCBs are stored in the Process Table, or proctab[]. This table is NPROC entries big. There are two variables in XINU that track the current number of processes in the system and the PID of the currently running process. This is a common strategy in many operating systems. These variables in XINU are called numproc and currpid.
In XINU PCBs are not called PCBs (which is unfortunate). Instead they are called pentry structures. This stands for "process table entry" - which I don't find very satisfying.
Let's take a look at the XINU process control block (pentry).
/* process table entry */ struct pentry { char pstate; /* process state: PRCURR, etc. */ int pprio; /* process priority */ WORD pregs[PNREGS]; /* saved registers PC, and PS */ int psem; /* semaphore if process waiting */ WORD pmsg; /* message sent to this process */ char phasmsg; /* nonzero iff pmsg is valid */ WORD pbase; /* base of run time stack */ int pstklen; /* stack length */ WORD plimit; /* lowest extent of stack */ char pname[PNMLEN]; /* process name */ int pargs; /* initial number of arguments */ WORD paddr; /* initial code address */ WORD pnxtkin; /* next-of-kin notified of death*/ short pdevs[2]; /* devices to close upon exit */ int fildes[_NFILE]; /* file - device translation */ };
Now let's look at the entries of current interest in the PCB:
#define PRCURR '\001' /* process is currently running */ #define PRFREE '\002' /* process slot is free */ #define PRREADY '\003' /* process is on ready queue */ #define PRRECV '\004' /* process waiting for message */ #define PRSLEEP '\005' /* process is sleeping */ #define PRSUSP '\006' /* process is suspended */ #define PRWAIT '\007' /* process is on semaphore queue*/ #define PRTRECV '\010' /* process is timing a receive */
Notice that there is no PID field in the PCB. The reason for this is that a processes PID in XINU is simply its index in the proctab. An alternative would be to assign processes continually incrementing PIDs (which would then have to be stored in the PCB). Eventually, the number would have to wrap. There are advantages and disadvantages to the XINU scheme. The chief advantage is simplicity. This scheme makes the O/S code small and easy to write.
The disadvantage is that PIDs are quickly reused (because of the small PID space). For example, say in a multi-user operating system two processes are cooperating and therefore sending each other messages. Message addressing is based on PIDs. If one of the processes dies, the small pid space means that it is possible for some new process to reuse the dead processes PID soon after its death. The other cooperating process may then send a message to the same PID thinking that the dead process is still around. This will cause major confusion for the sending and receiving processes. What can you do to avoid this problem? Think about it.