3.6 Example 5

  2113 wakeup (chan)
       {
         register struct proc *p;
         register c, i;
         c= chan;
         p= &proc[0];
         i= NPROC;
         do {
             if (p->p_wchan == c) {
               setrun(p);
             }
             p++;
         } while (--i);
       }

There are a number of similarities between this example and the previous one. We have a new concept however, an array of structures. To be just a little confusing, in this example it turns out that both the array and the structure are called “proc” (yes, “C” allows this). They are declared on Sheet 03 in the following form:

  0358 struct proc
       {
         char p_stat;
         ..........
         int p_wchan;
         ..........
       } proc[NPROC];

“p” is a register variable of type pointer to a structure of type “proc”.

    p = &proc[0];

assigns to “p” the address of the first element of the array “proc”. The operator “&” in this context means “the address of”.

Note that if an array has n elements, the elements have subscripts 0, 1, .., (n-1). Also it is permissible to write the above statement more simply as

    p = proc;

There are two statements in between the “do” and the “while”. The first of these could be rewritten more simply as

    if (p->p wchan == c) setrun (p);

i.e. the brackets are superfluous in this case, and since “C” is a free form language, the arrangement of text between lines is not significant.

The statement

    setrun (p);

invokes the procedure “setrun” passing the value of “p” as a parameter (All parameters are passed by value.). The relation

    p->p_wchan == c

tests the equality of the value of “c” and the value of the element “p_wchan” of the structure pointed to by “p”. Note that it would have been wrong to have written

    p.p_wchan == c

because “p” is not the name of a structure.

The second statement, which cannot be combined with the first, increments “p” by the size of the “proc” structure, whatever that is. (The compiler can figure it out.)

In order to do this calculation correctly, the compiler needs to know the kind of structure pointed at. When this is not a consideration, you will notice that often in similar situations, “p” will be declared simply as

    register *p;

because it was easier for the programmer, and the compiler does not insist.

The latter part of this procedure could have been written equivalently but less efficiently as

      ............
      i = 0;
      do
        if (proc[i].p_wchan == c)
          setrun (&proc[i]);
      while (++i < NPROC);