#ifndef EVENT_H #define EVENT_H /* $Id: event.h,v 10.1 92/10/06 23:08:27 ca Exp $ */ #include "sim.h" #include "heap.h" #include "mempool.h" #include "packet.h" #include "component.h" #include "eventdefs.h" #define EVENT_POOL_SIZE 100 typedef int Evtype; typedef struct _event { struct _event *ev_next; Evtype ev_type; tick_t ev_time; PFP ev_rtn; Component *ev_src; Component *ev_dest; Packet *ev_pkt; caddr_t ev_arg; } Event; /*#define EVDATA(q_elt) ((Event *) (q_elt->qe_data))*/ /*#define EVQ_HEAD(q) (q->q_head)*/ Event *ev_member(), *ev_dequeue(); void ev_toggle_debug(), ev_fire_with_time(), ev_fire_before_time(), ev_dequeue_by_type(), ev_dequeue_by_comp_and_type(), ev_dequeue_by_time(), ev_set_delay(); tick_t ev_get_delay(); #ifdef _EVENT_ tick_t event_standard_time = 0L; #ifdef INLINE tick_t event_delay_between_events = 0; /* Delay in uSec */ Heap *event_queue = (Heap *) NULL; Mempool *event_mempool = NULL; int evdebug = 0; #endif /* INLINE */ #else /* if not _EVENT_ */ extern tick_t event_standard_time; #ifdef INLINE extern tick_t event_delay_between_events; /* Delay in uSec */ extern Heap *event_queue; extern Mempool *event_mempool; extern int evdebug; #endif /* INLINE */ #endif /* _EVENT_ */ #define ev_now() event_standard_time /* Functions defined inline for GCC */ #ifndef INLINE Event *ev_enqueue(); #else /* frees ev's storage */ static inline ev_free(ev) register Event *ev; { if(! ev) { return(FALSE); } mp_free(event_mempool, (char *) ev); return(TRUE); } /* allocate and return an empty event structure */ static inline Event *ev_alloc() { return((Event *)mp_alloc(event_mempool)); } /* add ev to the event queue, preserving time order */ static inline ev_adda(ev) register Event *ev; { heap_insert(event_queue, ev->ev_time, (caddr_t)ev); return(TRUE); } /* cause an event to happen */ static inline ev_fire(ev) Event *ev; { /* bump simulator time if this event is later than the current time */ if(event_standard_time < ev->ev_time) { event_standard_time = ev->ev_time; } /* usleep() is a BSDism, and sleep() would be much too long here. So, if not BSD, don't do anything. */ #ifdef BSD /* Wait for some amount of time (if necessary) */ if (event_delay_between_events) usleep(event_delay_between_events); #endif /* BSD */ if (evdebug) printf("Firing event at time %d, %d left in queue\n", event_standard_time, event_queue->size); if (record_flag) if (ev->ev_type & EV_CLASS_RECORD) fprintf(record_file, "%u '%s' %d %d\n", ev_now() * USECS_PER_TICK, ev->ev_dest->co_name, ev->ev_type, ev->ev_arg); /* execute routine */ (*(ev->ev_rtn))(ev->ev_src, ev->ev_dest, ev->ev_type, ev->ev_pkt, ev->ev_arg); ev_free(ev); return(TRUE); } /* enqueue a given event. If ev is NULL, allocate an event and then enqueue. it. Returns a pointer to the event. */ static inline Event *ev_enqueue(type, src, dest, time, rtn, pkt, arg) Evtype type; Component *src, *dest; tick_t time; PFP rtn; Packet *pkt; caddr_t arg; { Event *ev; /* Allocate an event to enqueue */ if(evdebug) { printf("ev_enqueue: allocating event\n"); } if(! (ev = ev_alloc())) { if(evdebug) { printf("ev_enqueue: no memory for event object\n"); } return((Event *) NULL); } ev->ev_type = type; ev->ev_time = time; ev->ev_rtn = rtn; ev->ev_src = src; ev->ev_dest = dest; ev->ev_pkt = pkt; ev->ev_arg = arg; if(! ev_adda(ev)) { ev_free(ev); return((Event *) NULL); } return(ev); } #endif /* INLINE */ #endif /* EVENT_H */