XML

kent logo

CO538 Anonymous Questions and Answers Keyword Index

This page provides a keyword index to questions and answers. Clicking on a keyword will take you to a page containing all questions and answers for that keyword, grouped by year.

To submit a question, use the anonymous questions page. You may find the keyword index and/or top-level index useful for locating past questions and answers.

Keyword reference for timers

2012

Question 48 (2012):

Submission reference: IN2294

I'm trying to do Task 3 of Life on Mars, but I'm having issues with the timeout - specifically, the actual time it waits is often absurdly long, sometimes minutes.

    tim ? t
    PRI ALT
      tim ? AFTER t PLUS CAMERA.SCAN.TIME     -- 2 seconds
        ...  turn robot 90 degrees and increment a 'count'
      BLOB b:
      camera ? b
        ...  if 'b' has the sought colour, set 'searching' FALSE & report to mission control

It doesn't matter whether there are any blobs in view or not, and recompiling or rerunning doesn't produce consistent results.

Answer 48:

You don't show the enclosing loop. From what you show, I'm guessing something like:

    WHILE searching AND (count < 4)
      SEQ
        tim ? t
        PRI ALT
          tim ? AFTER t PLUS CAMERA.SCAN.TIME     -- 2 seconds
	    ...  turn robot 90 degrees and increment a 'count'
          BLOB b:
          camera ? b
	    ...  if 'b' has the sought colour, set 'searching' FALSE & report to mission control

Now, suppose a BLOB is reported on camera but not with the sought colour; then execution goes round the loop and the timeout is reset for another 2 seconds. The 'mandelbot' rock formations are reported (by the image processing processes running in parallel with your robot.control) as potential BLOBs down the camera channel, but will have different colours to the BLOBs sought by mission control. Further, so long as a potential blob is in view, it will continue to be reported down camera at least once every CAMERA.SCAN.TIME. In practice, CAMERA.SCAN.TIME is a bit generous and blobs may be reported a little more often than that.

So, if the sought BLOB is not in vision but something else is and that something gets sent down camera before your code times out, the potential blob is ignored and your timeout is reset for 2 more seconds. This can carry on indefinitely, the timeout never happens and your robot in never told to turn!

See "Choice" slide 46 for the right way to set the timeout times.

Keywords: mars , timers

2011

Question 46 (2011):

Submission reference: IN2079

I get:

    Error-occ21-q7.occ(40)- cannot open file "time.module"

I've looked in lib and sure enough it isn't there...

Answer 46:

This looks like a response to the answer in Question 43 (2011). It looks like the search path set up for you on the Transterpreter doesn't reach all the libraries – which would be our fault.

However, that question was seeking a delay process and I'm assuming that that is what you are still seeking? The function of delay in the "time.module" is, as its documentation says, identical to the pause process given in your starter files for q1, q2, q3 and q4 (and e1). Just copy and use that – it's only these 7 lines of code:

    PROC pause (VAL INT delay)
      TIMER tim:
      INT t:
      SEQ
        tim ? t
        tim ? AFTER t PLUS delay
    :

Keywords: q7 , delay , timers


Question 43 (2011):

Submission reference: IN2077

I get:

    Error-occ21-q7.occ(133)- delay is not declared

I looked at the occam documentation and it is there! What am I doing wrong?

Answer 43:

Indeed it is: delay. However, if you scroll up from this documentation, you will see that it's in the module time. To use this, you will need the line:

    #INCLUDE "time.module"

somewhere before you use delay in your code (next to the #INCLUDE line for "course.module").

We did not put the delay in the course module. It seemed too simple and you have been using it in many of your provious assignments (where its code was given in the starter files). We did not put it in the starter file for the Dining Philosophers' animation, since many solutions would use TIMERs directly.

POSTSCRIPT: apologies, I was confused by the incosistency in the names we chose! The starter files for q1..q4 have a delay process called pause. This has the same functionality as the delay process called delay in the "time.module".

Keywords: q7 , delay , timers

Referrers: Question 46 (2011)

2010

Question 52 (2010):

Submission reference: IN1948

Is it possible to loop over some code for a specified duration? Something like:

  SEQ
    tim ? t 
    PRI ALT 
      NOT (tim ? AFTER t PLUS 2000000)
        ...  still waiting, do stuff
      SKIP
        SKIP

I've had a look over lecture slides and cannot find anything. I want to be certain I am receiving all the blobs from the camera before I start searching them for the correct colour.

Answer 52:

Yes, but this is typically simpler than the code you have above. The "AFTER" operator can be used to test whether one time is after another, so can be used in conditionals. For example:

  TIMER tim:
  INT start, stop:
  SEQ
    tim ? start
    stop := start PLUS 2000000
  
    INITIAL BOOL waiting IS TRUE:
    WHILE waiting
      INT now:
      SEQ
        tim ? now
        IF
          stop AFTER now
            ...  still waiting, do stuff
          TRUE
            waiting := FALSE

There are probably better (more elegant) ways to code this, but that should do what you want. If you really wanted to use an ALT with a timeout it could be coded something like:

    TIMER tim:
    INT t:
    SEQ
      tim ? t
  
      INITIAL BOOL waiting IS TRUE:
      WHILE waiting
        PRI ALT
          tim ? AFTER (t PLUS 2000000)
            -- timeout reached
            waiting := FALSE
          SKIP
            ...  still waiting, do stuff

However, this is polling a timer ...so probably isn't the best way to go about it. How about:

    TIMER tim:
    INT t:
    SEQ
      tim ? t
  
      INITIAL BOOL waiting IS TRUE:
      WHILE waiting
        PRI ALT
          tim ? AFTER (t PLUS 2000000)
            -- timeout reached
            waiting := FALSE
	  BLOB blob:
          camera ? blob
            ...  check out this blob (if target, set waiting FALSE)

? That's much better, :). Now, it only does stuff if the camera sends a blob or the timeout happens – and this is the basic pattern for setting timeouts on waiting for things to happen!

You may need some more stuff in the above ... so that you can tell whether you exit the loop because you found the blob or timed out.

Keywords: timers , mars , polling

Referrers: Question 61 (2010)

2007

Question 68 (2007):

Submission reference: IN1453

Regarding time: suppose t is the current time, from a TIMER, and t1 is t PLUS 100. For 100ms, (t AFTER t1) will be FALSE. As soon as the condition becomes TRUE, if I want to increase their difference again by 100, am I going to add 101 or 100?

I know is a bit silly but I have been playing around with the maths and it seems logical to add 101 instead of 100.

Answer 68:

occam-pi TIMERs work to microseconds (us), not milliseconds (ms). This is just to set your question in the right units and does not otherwise affect the point you raise.

Suppose we have:

  SEQ
    tim ? t
    tim ? AFTER t PLUS 0

where tim is a TIMER and t is an INT. The last line does not complete until the time on tim is AFTER what was recorded the line before. Depending how far it was through the hardware timer's microsecond when that time was recorded, the last line may have to wait: if the timer has not moved on by (at least) one microsecond, the last line will have to wait.

Suppose we have:

  SEQ
    tim ? t
    tim ? AFTER t PLUS n

where n is a non-negative INT. In this case, the last line will wait until the timer has moved on by (at least) (n + 1) microseconds (from the time recorded in the previous line).

[If n were -1, the last line will not have to wait (since the time on the timer will be AFTER one microsecond before the previous line executed).]

As you have observed, this is a little subtle (and that's bad!). It would be more logical if occam-pi had an AFTER.OR.EQUAL operator, that related to >= in the same way as AFTER relates to >. Then, we could have:

  SEQ
    tim ? t
    tim ? AFTER.OR.EQUAL t PLUS n

In which case, the last line would wait until the timer had moved on by (at least) n microseconds (from the time recorded in the previous line). But there is no AFTER.OR.EQUAL operator!

For practical applications, however, this microsecond discrepancy will not matter. To set up a regular series of timeouts, evenly spaced every n microseconds, the correct template is:

  TIMER tim:
  INT timeout:
  SEQ
    tim ? timeout
    timeout := timeout PLUS n
    WHILE <some condition>
      SEQ
	tim ? AFTER timeout
	timeout := timeout PLUS n   -- set up next timeout value
	...  do some stuff

Notice that an actual time value is only recorded once – before the loop is even entered. Inside the loop, the values in timeout advance in exact increments of n microseconds – i.e. the timeouts in the series are always n microseconds apart from each other.

The result of having to write AFTER, rather than AFTER.OR.EQUAL, is that that series is always one microsecond after the series we might have been expecting (because the initialisation of that original timeout value, before loop entry, was one microsecond after what we might have thought).

Of course, if an incorrect template were used – such as:

  TIMER tim:
  INT timeout:
  WHILE <some condition>
    SEQ
      tim ? timeout
      tim ? AFTER timeout PLUS n
      ...  do some stuff

then timeouts of (n + 1) microseconds from the start of each loop are being set. The actual series of timeouts will be separated by (n + 1) microseconds together with however long it takes to do the rest of the stuff in the loop. This will not be a regular series!

For information, here is a correct template for setting up a regular series of timeouts (separated by n microseconds) in a process that also has to deal with other events:

  TIMER tim:
  INT timeout:
  SEQ
    tim ? timeout
    timeout := timeout PLUS n
    WHILE <some condition>
      PRI ALT
	tim ? AFTER timeout
	  SEQ
	     timeout := timeout PLUS n   -- set up next timeout value
	     ...  response to the timeout
	<another guard>
	  ...  response to this other guard
	<yet another guard>
	  ...  response to this other guard

where we have given the timeout highest priority (over the other events). Of course, some applications may need to give other events higher priority ... or even deal with them fairly (see Question 62 (2007)).

In all the above analysis, we are assuming perfect timers and that the process being considered is running on a sufficently fast processor (that can complete whatever else the process has to do before its next timeout is due). In practice, that won't always happen – especially when there are other processes sharing that same processor. Dealing with this takes us into the realm of hard and soft real-time systems, which was not included in this year's material (see Question 63 (2007)).

For interest however, you may note that, with the correct template, if a timeout is missed (because the process didn't get around to the timeout line in time), the timeout line will not delay anything – i.e. the response will be late ... but gets done as soon as possible. The next set timeout will still be for the original series schedule. So long as the processor can get through its response a bit quicker, the process will get back on schedule. This is what is needed for many soft real-time systems. At exceptionally busy times, some deadlines may be missed ... but it gets back on schedule as soon as the busy period ends. Note the emphasis on exceptionally.

Summary: the line:

  tim ? AFTER timeout

does not terminate until the time value in the timer tim is AFTER the value of timeout. This means that it is guaranteed to wait until the time is (at least) one microsecond after timeout. In practice, it may have to wait longer (for the run-time kernel to get around to scheduling this process to run on some processor core).

If we wanted the guarantee to be for it to wait until the time is (at least) timeout, we should write:

  tim ? AFTER (timeout MINUS 1)

Because the guarantees have that "(at least)" in them, there is not much need for the above subtlety. Guaranteeing to wait until (at least) one microsecond after timeout is also a guarantee to wait until (at least) after timeout.


Keywords: timers

Referrers: Question 72 (2007)


Question 63 (2007):

Submission reference: IN1429

Give examples of real-time systems that combine hard and soft real-time concepts and a brief description on the functionalities of one of the systems.

Answer 63:

The course did cover issues dealing with time (e.g. TIMER declarations, the occam-pi model of time, timeouts and timeout guards in ALTs). You need to be comfortable about programming loops that have time-periodic cycles (e.g. a process that outputs once per second how many inputs it received in the previous second).

However, this (2008) year we did not consider the common problems of real-time systems: how to calculate worst case response times, how to design systems so that such things can be calculated and minimised, and the concepts of hard and soft real-time. So, these things are not examinable.

For information, a hard real-time system is one whose specified deadlines must always be met – for example, collision detection systems in autonomous vehicles or the control avionics in a fly-by-wire airplane. If those deadlines get missed, the system crashes – literally!

A soft real-time system is one whose specified deadlines should be met most of the time – but only lead to temporary inconvenience when missed, with the system continuing to work and recovering to full functionality in time. Examples include: delivery of video data to a phone, processing bar-scanner readings at a supermarket checkout station, processing web forms for e-commerce.

An example of a system having elements of both: an avionics system combining the presentation of air-flow data to the head-up display for the pilot (soft) with the computation of wing surface movements, based on that air-flow data and other things, to keep the aircraft in stable flight (hard).

Keywords: timers

Referrers: Question 68 (2007)

2006

Question 86 (2006):

Submission reference: IN1094

In the class you wrote down an ALT used for timing yet still taking in data, but I didn't get the final version written down. You made some adjustment that meant the timing period was only calculated once I think. Could you give me the code again? Thanks.

Answer 86:

Hi – you need to be a bit quicker taking notes ... we did spend almost an hour on this!

All we were doing was waiting for either a channel input or a timeout. occam-pi has a particularly simple, efficient and elegant mechanism for such things – the ALT. Here is the process we developed. It's a clock process that ticks with a regular, but resettable, period. It doesn't do anything until a period is supplied (down its reset channel):

    PROC clock (CHAN INT reset?, CHAN BOOL tick!)
      TIMER tim:
      INT timeout, period:
      SEQ
	reset ? period
	tim ? timeout
	timeout := timeout PLUS period
	WHILE TRUE
	  PRI ALT
	    reset ? period
	      SKIP
	    tim ? AFTER timeout
	      SEQ
		tick ! TRUE
		timeout := timeout PLUS period
    :

Note the standard idiom when setting up a sequence of regular timeslices: check the actual time just the once ... then calculate the first time-out time before going into the loop. Inside the loop and when a timeslice ends, calculate the next timeout value from the last one – i.e. don't check the actual time again and calculate from that:

	    tim ? AFTER timeout
	      SEQ
		tick ! TRUE
		tim ? timeout                    -- this is a mistake
		timeout := timeout PLUS period

because that means the timeslices will not have regualar periods. If the above were coded, the time betweem timeouts is period plus however long you have to wait for the tick to be taken plus however long it takes to check the time and calculate the next timeout.

With the original code above, the time betweem timeouts is period ... at least, the run-time system will do its best to make it so. If sometimes it takes more than period microseconds before the tick is taken, the next timeout will follow immediately. So long as that doesn't keep happening, the system will get back on schedule – the code is real-time stable.

There is an argument for checking the actual time again on receipt of a reset period. Suppose the current period were 10 seconds and we were 2 seconds into this when a reset arrives telling us to start ticking every second. The code given above would wait until the end of the currently defined period – i.e. another 8 seconds – before the next timeout occurs and, then, it starts ticking every second. [My windscreen wipers work like this when on intermittent sweeps: when I switch them to speed up, they wait until the end of (long) period before changing speed.]

Depending on the application, that may not be acceptable. If not, there is an easy solution:

    PROC clock (CHAN INT reset?, CHAN BOOL tick!)
      TIMER tim:
      INT timeout, period:
      SEQ
	reset ? period
	tim ? timeout
	timeout := timeout PLUS period
	WHILE TRUE
	  PRI ALT
	    reset ? period
	      SEQ
		tick ! TRUE     -- immediately start a new sequence of ticks
		tim ? timeout
		timeout := timeout PLUS period
	    tim ? AFTER timeout
	      SEQ
		tick ! TRUE
		timeout := timeout PLUS period
    :

Now, if a reset to 1 second arrives 2 seconds into a 10 second period, it immediately starts ticking with the lower period (= faster rate). Whether that immediate tick in response to the reset should be done should be discussed with the engineer who is going to use this device. It's easily removed!

Keywords: timers

2004

Question 110 (2004):

Is this the correct piece of code for waiting a random time ?

    SEQ          
      seed := seed + id
      i, seed := random(num, seed)
      tim ? t
      tim ? AFTER t PLUS i

Answer 110:

More or less, yes. Make sure you initialise "seed" appropriately though -- the code above initialises it based on itself (if undefined, it'll stay undefined). As covered in the seminars, a quick way to get an initial seed value is:

    tim ? seed
    seed := (seed >> 2) + 1   -- maybe also add in the `id'

Remember also that your seed should be explicitly initialised like this just once -- before loop entry. Within the loop, cycling through the philosopher's life, the seed value gets updated as you use the random function. The sequence of seed values takes you through the "random" numbers. If you re-initialise the seed every time round the loop, the computed randomness will be lost.

Keywords: q7 , timers


Question 59 (2004):

Hi, what is the best way to to wait 1 second within a loop ? (Required for q5)

Answer 59:

See the answer to Question 80 (2000).

Keywords: timers

2002

Question 37 (2002):

Could you please explain a little more how you would go about implementing the random time delay? I have read through the previous questions on it but I'm still a little lost. Is the time delay between philosophers doing different actions or in the display process?

Answer 37:

It's in the philosopher processes - not the display.

The question says:

Thinking and eating by the philosophers should be modelled by random (but finite!) delays

In the "philosopher" process there are two folds:

  <!--{{{  think-->
  SKIP
  <!--}}}-->

and:

  <!--{{{  eat-->
  SKIP
  <!--}}}-->

You should replace the SKIPs by random delays.

Keywords: q7 , random , timers

2000

Question 80 (2000):

The question says:

"Thinking and eating by the philosphers should be modelled by random (but finite!) delays."

Assuming we have obtained a random number, what's the best way to implement the delay ... i.e. pause execution for a random time? Is there a wait(time) function or such like?

Answer 80:

See slide 4-40 and sections 3.4/3.5 of the "OCCAM2 CHECKLIST" paper. Spelling it out:

  TIMER tim:
  INT t:
  SEQ
    tim ? t
    tim ? AFTER t PLUS waiting.time

Keywords: q7 , timers

Referrers: Question 59 (2004)


Question 79 (2000):

When it comes to TIMERs, how is the time counted? Does the internal enviornment time in nanoseconds or microseconds? Also does it go like this:

  1000000 nanoseconds = 1 second
  10000 microseconds = 1 second

Answer 79:

occam TIMERs, in KRoC Solaris/Linux systems, increment every microsecond. And, for information:

  1000000000 nanoseconds = 1 second
  1000000 microseconds = 1 second

Keywords: timers

Valid CSS!

Valid XHTML 1.0!

This work is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License.
Last modified Mon May 20 13:50:34 2013
This document is maintained by Fred Barnes, to whom any comments and corrections should be addressed.