#ifndef _EVENT_H #define _EVENT_H /* -- event is a multi purpose keyword and context-aware event myev1,myev2 -- define user events (w/o device id) on event ("eventname",devid) call foo on event ("eventname",devid) stop await event("eventname",devid) await event("eventname",devid) delay timeout proc handler { devid=event } event(myev1) -- raise event */ typedef enum { EVDEVICE, // ADC, DAC ,... EVMESSAGE, // received user message $..$ EVSTREAM, // Generic IO stream communication, serial link, ... EVTIMER, // periodoc timer, timers must be handled by host appl. and started and stopped programmatically EVUSER, // user defined events EVSIGNAL, // signal event (e.g., hardware signals) EVIO, // single blocked VM IO op, e.g., INNUMBER (missing data) or OUTNUMBER (buffer full) EVNONE } evtype_t; /* Event handler. Event handlers can be shared by multiple tasks. If an event is raised, all tasks are scheduled (depending on context entry), except IO events with blocked ops. There are in-line (await) and procedure-call events. */ #define EVNAMELEN 4 typedef struct { /* Event names must be at least 4 letters long but only first 4 letters are (case-sensitive for speed) considered. */ char name[EVNAMELEN]; // only first four letters are relevant and unique! index_t index; evtype_t type; char enabled; char latch; // event latch if event occured bit no listening tasks (huh, racy, when to clear?) address_t handler[MAXTASKS]; // code address of handler or 0 if in-line waiting for event index_t pending; index_t listeners; context_t *context[MAXTASKS]; // VM context (one per task) index_t io[MAXTASKS]; // for IO events with blocked VM IO opes, task specific channel/fd number int (*send)(); // optional sender function, primarily used for signal sending } event_t; /* Event tbale structure */ typedef struct { event_t table[MAXEVENTS]; int32_t mask; index_t top; index_t user; // start of user events index_t last; } events_t; /* Events are shared by all tasks and VMs! */ extern events_t events; #define EVCLEAR(mask,evindex) mask&=~(1<