/* Output from p2c, the Pascal-to-C translator */ /* From input file "netsim.pas" */ /* p2c: Note: Remember to call _netsim_init() in main program */ #include #define NETSIM_G #include "netsim.h" typedef struct enode { float idx; struct enode *skip, *next, *prev; erec *e; } enode; Static float current_time; Static enode *eventlist; Static boolean save_events; Static enode dummy_node; Static erec dummy_event; Local Void einsert(erec *x, enode *current) { enode *temp; temp = (enode *)Malloc(sizeof(enode)); /* link in new node to previous and next nodes */ temp->prev = current->prev; temp->next = current; /* set indexing fields */ temp->skip = current; temp->idx = current->e->time; /* set event pointer */ temp->e = x; /* fix previous node to point to new node, unless current is present head of list */ if (current->prev != NULL) current->prev->next = temp; /* fix next node to point to new node */ current->prev = temp; /* inserted at head of list, replace eventlist */ if (current == eventlist) eventlist = temp; /* inserted at tail of list, add shortcut to prevent O( N^2 ) performance for (nearly) ordered input by always having first node's index point to last node */ if (current == &dummy_node && eventlist != temp) { /*NOTE: above also prevents loop when only one node on list */ eventlist->skip = temp; eventlist->idx = temp->e->time; } } Void queue_event(erec *e) { enode *current; if (e->time < current_time) { printf( "%%NETSIM - Event with illegal time stamp [% .5E] received by Queue_Event.\n", e->time); return; } current = eventlist; while (current->next != NULL) { /*not at end of list... */ if (e->time >= current->idx) /* use skip pointer to bypass N nodes */ current = current->skip; else { /* check the node's event time value */ if (e->time < current->e->time) { /* not found yet... */ einsert(e, current); return; } current = current->next; } } einsert(e, current); /* proper place to insert new node */ } erec *next_event() { erec *Result; do { current_time = eventlist->e->time; Result = eventlist->e; eventlist = eventlist->next; if (!save_events) { Free(eventlist->prev); eventlist->prev = NULL; } } while (current_time < 0.0); /* i.e., non-cancelled event, dummy event always triggers this condition */ if (eventlist == NULL) { /* was at end of list, just read dummy event, return NIL event pointer */ Result = NULL; eventlist = &dummy_node; /*reset eventlist to point to 'empty' list*/ } return Result; } Void cancel_events(long src) { enode *current; current = eventlist; while (current != &dummy_node) { /*at end of list... */ if (current->e->src == src) /* cancel this event by negating time */ current->e->time = -current->e->time; current = current->next; } } float sim_time() { return current_time; } Void set_save_mode() { save_events = true; } Void set_event_tracking(symbol_node *options) { } void _netsim_init() { static int _was_initialized = 0; if (_was_initialized++) return; dummy_event.time = 1.0e30; dummy_event.next = -1; dummy_event.src = -1; dummy_event.dst = -1; dummy_event.msg = NULL; dummy_node.idx = 1.0e30; dummy_node.next = NULL; dummy_node.prev = NULL; dummy_node.skip = NULL; dummy_node.e = &dummy_event; eventlist = &dummy_node; current_time = 0.0; save_events = false; } /* End. */