Mon 16 Mar 11:09:06 CET 2026

This commit is contained in:
sbosse 2026-03-16 11:10:33 +01:00
parent 9baeec2334
commit e6ab306721

96
src/event.h Normal file
View File

@ -0,0 +1,96 @@
#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<<evindex)
#define EVSET(mask,evindex) mask|=(1<<evindex)
#define EVISSET(mask,evindex) mask & (1<<evindex)
#define EVNAMECOPY(name1,name2) *((int32_t *)name1)=*((int32_t *)name)
/* compare the four first letters of an event name */
#define EVNAMECMP(name1,name2) *((int32_t *)name1)==*((int32_t *)name2)
#define EVPENDING(mask) mask!=0
void EventInit(char reset);
int AddEvent(char *name, index_t device, evtype_t type);
int AddEventSender(char *name, index_t device, int (*send)());
int FindEvent(char *name, index_t device);
int HandleEvents(context_t *C);
int OffEvent(char *name, index_t index, context_t *C);
int OffEventIndex(index_t evindex, context_t *C);
int OnEvent(char *name, index_t device, address_t call, context_t *C);
int OnEventIndex(index_t evindex, address_t call, context_t *C);
int RaiseEvent(char *name, index_t device);
int RaiseEventIndex(index_t evindex);
int SendEvent(char *name, index_t device);
int SendEventIndex(index_t evindex);
void EventCleanUp(context_t *C);
int HandleTimeout(context_t *C);
/* host software notification (callback) */
typedef enum {
NOTIFYMSG,
NOTIFYNET,
NOTIFYVM
} notify_t;
void Notify(notify_t cls, int arg, void *data);
void OnNotify(void (*callback)(notify_t cls, int arg, void *data));
#endif