Uppsala University
Listen to this web page

Uppsala University Department of Information Technology            

Notes on wait_event()

The wait_event system call

About every 20:th ms the LegOS operating system makes a context switch and checks if there are any other tasks that should be running instead of the current task. All tasks waiting in the OS are either waiting because that current executing task has a higher priority or because it is waiting for some condition to be fulfilled.

If a task wants to suspend itself until a certain condition has been fulfilled, e.g. until some sensor has been pressed, it can call the wait_event system call. The wait_event system call is declared as wakeup_t wait_event(wakeup_t(*wakeup) (wakeup_t), wakeup_t data); . The function wait_event takes the name of a wakeup function as its first argument. Every time the OS does a context switch it will release the task with the highest priority which wakeup function returns a non-zero value (unless the current executing task has higher priority).

As second argument to wait_event a parameter is given that can be used by the wakeup function to determine if the calling task should be invocted. Both the argument and the return value of a wakeup function should be of wakeup_t type.

Examples

For example, a wakeup function which returns if the touch sensors 1 or 3 are pressed can be declared like:

wakeup_t sensor_press_wakeup(wakeup_t data) {
  return TOUCH_1 || TOUCH_3;
}

A task that wants to wait for the event that one of the two sensors has been pressed, e.g. to move a vehicle away from the obstacle causing the sensors to react, are calling the wait_event function with sensor_press_wakeup as argument, something like:

...
/* run some code */
...
wait_event(sensor_press_wakeup, NULL);
...
/* run code to move away from obstacle */
...

Many LegOS system calls are indirectly implemented as wait_event calls, e.g. semaphore handling and the sleep and msleep commands. For example the code for the operating system call msleep, which delays the current task for some ms, is declared as (slightly simplified, see the file tm.c for the real code):

unsigned int msleep(unsigned int msec)
{
  (void) wait_event(tm_sleep_wakeup, sys_time + msec);
  return 0;
}

The corresponding wakeup function tm_sleep_wakeup looks like:

static wakeup_t tm_sleep_wakeup(wakeup_t data) 
{
  return ((time_t)data <= sys_time);
}

That is, the msleep function calculates the absolute time the calling task should be waken up and the tm_sleep_wakeup will return false (= 0) as long as system time is smaller than this value.

In most cases you don't need to give any arguments to your wakeup function but instead checks if some global variable or sensor has been set.


Last update: Mon, 8 Sep 2003 11:16:07 Responsible: Tobias Amnell. Web: Contact
Copyright © 2004 Uppsala University, Department of Information Technology.
Show printer-friendly page      View this page.      Edit this page.