# KRoC Frequently Asked Questions

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

Last Modified 7th April 2002

- I get a ``KRoC: bsyscalls: unable to create semaphores: ...'' type error. Uh ?
- How do I pause a process for a specific amount of time ?
- How do I setup/use a shared channel ?
- How do I use the random function ?
- My program deadlocked or range/STOP errored. Uh ?

### 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:

- any-to-one, multiple writers and one reader (multiplex). Semaphore required for the writers.
- one-to-any, one writer and multiple readers (farmer/worker). Semaphore required for the readers.
- any-to-any, multiple writers and multiple readers (farmers/workers). Two semaphores required, one for the readers and one for the writers.

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 `INT`s), 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:

- read the current time, eg, ```tim ? t`''
- wait until after a particular time, eg, ```tim ? AFTER t`''

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.