KRoC Frequently Asked Questions

Maintained by: Fred Barnes (frmb2@ukc.ac.uk)

Last Modified 7th April 2002



My program deadlocked or range/STOP errored. Uh ?

added 17/02/2002

On KRoC/Linux, use the `-d' flag to the `kroc' command to turn on debugging. You'll need to re-compile all the various bits of code used in order to get useful debug information. When the program crashes now, it will report where the error happened. If the program deadlocks, KRoC will print information about any processes which were blocked, either on channel I/O or an ALT.


How do I use the random function ?

added 18/02/2002

A random number generator is provided in the course library. It's header (interface) reads:

    INT, INT FUNCTION random (VAL INT upto, seed)
This returns an integer in the range 0 to `(upto - 1)' inclusive as the first result and a new seed as the second result. One would normally use this in the following way:
    INT v, seed:
    SEQ
      ...  initialise seed correctly

      v, seed := random (20, seed)

      ...  use v (in the range 0-19 inclusive)
The seed must be initialised to an integer between 1 and `((MOSTPOS INT) - 1)' inclusive. A useful method is to get an initial seed from a TIMER then adjust to make it a valid seed.


How do I setup/use a shared channel ?

added 18/02/2002

A channel can be made shared in one of three ways:

To use semaphores, you need to include the file ``semaphore.inc'' in your occam program:
    #INCLUDE "semaphore.inc"
Since standard occam doesn't permit automatic sharing of channel-ends, you need to make explicit the shared nature of channels and data (semaphores):
    CHAN OF INT shared.chan:
    #PRAGMA SHARED shared.chan
    SEMAPHORE chan.sem:
    #PRAGMA SHARED chan.sem
The `#PRAGMA SHARED' declaration must immediately follow the declaration. You can in a similar way share parameters and abbreviations:
    PROC foo (CHAN OF INT to.harvester, SEMAPHORE harvester.sem)
      #PRAGMA SHARED to.harvester, harvester.sem

      ...
    :
As a working example, the following code shows a simple multiplexing channel (of INTs), where multiple workers feed into a single harvester:
    #USE "course.lib"
    #INCLUDE "semaphore.inc"

    PROC worker (VAL INT id, CHAN OF INT out, SEMAPHORE out.sem)
      SEQ i = 0 FOR 10
        INT v:
        SEQ
          v := (id + 1) * i
          ...  compute some more

          -- need to claim semaphore before using shared channel
          claim.semaphore (out.sem)

          out ! v

          -- and release again afterwards
          release.semaphore (out.sem)
    :

    PROC harvester (CHAN OF INT in, CHAN OF BYTE out)
      WHILE TRUE
        INT v:
        SEQ
          in ? v
          out.int (v, 0, out)
          out ! '*n'
    :

    PROC farm (CHAN OF BYTE keyboard, screen, error)
      CHAN OF INT work.done:
      #PRAGMA SHARED work.done
      SEMAPHORE work.sem:
      #PRAGMA SHARED work.sem:
      SEQ

        -- initialise the semaphore to 1 (binary semaphore/mutex)
        initialise.semaphore (work.sem, 1)

        -- do network
        PAR
          harvester (work.done, screen)
          PAR i = 0 FOR 20
            worker (i, work.done, work.sem)
    :


How do I pause a process for a specific amount of time ?

added 21/02/2002

Time in occam is absolute, ie, there is no direct way to say ``sleep for n micro-seconds''. The two things available are:

Using both of these provides the mechanism to sleep for a certain amount of time. The following PROC defines a procedure which sleeps for the specified period of time (given as a parameter in micro-seconds (one millionth of a second)), then returns:
    PROC udelay (VAL INT usecs)
      TIMER tim:
      INT t:
      SEQ
        tim ? t
        tim ? AFTER (t PLUS usecs)
    :
The value of `usecs' can be any valid integer. Negative numbers cause no delay, since that time has already passed. The maximum delay is ``MOSTPOS INT'' (2,147,483,647), but using value this big is unlikely to work, due to the wrap-around caused by the very slight delay between reading the time and waiting for `t PLUS usecs'. The maximum delay turns out to be about 35 minutes.


I get a ``KRoC: bsyscalls: unable to create semaphores: ...'' type error. Uh ?

added 07/04/2002

This error happens when the system runs out of (system-V) style semaphores, which are used in the handling of blocking system-calls. Sometimes when programs exit they leave behind semaphores, usually if the program crashes in an unexpected way. KRoC sometimes leaves behind semaphores, but efforts are made to clean-up after itself. However, semaphores sometimes get left behind if KRoC exits without the opportunity to clean-up the blocking system calls (if sent a KILL signal or if it segfaults internally).

The fix is to delete the semaphores which are no longer needed. On most modern systems, /proc/sysvipc/sem exists which can be consulted for any specific offending semaphore identifiers. Care should be taken not to remove semaphores which are in use by other programs (sane programs should use the semaphore permission bits to stop others intefering, but some don't). A little utility to remove semaphore identifiers can be downloaded here (2.1k). To compile it, do:

    gcc -o rmsem rmsem.c
This (rmsem) can be run without arguments in which case it will try and delete all semaphore identifiers, or with specific identifiers as arguments. Removing a semaphore which a program is using will probably cause the program to exit with an error.