FILE EVTqueue.c
MEMBER OF process XSPICE
Public Domain
Georgia Tech Research Corporation
Atlanta, Georgia 30332
PROJECT A-8503
AUTHORS
9/12/91 Bill Kuhn
MODIFICATIONS
<date> <person name> <nature of modifications>
SUMMARY
This file contains functions that place new events into the output and
instance queues.
INTERFACES
void EVTqueue_output(
CKTcircuit *ckt,
int output_index,
int udn_index,
Evt_Output_Event_t *new_event,
double posted_time,
double event_time)
void EVTqueue_inst(
CKTcircuit *ckt,
int inst_index,
double posted_time,
double event_time)
REFERENCED FILES
None.
NON-STANDARD FEATURES
None.
============================================================================*/
#include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h"
#include "ngspice/mif.h"
#include "ngspice/evt.h"
#include "ngspice/evtudn.h"
#include "ngspice/evtproto.h"
EVTqueue_output
This function places the specified output event onto the output
queue. It is called by EVTload during a transient analysis.
The linked list in the queue for the specified output is
searched beginning at the current head of the pending events
to find the location at which to insert the new event. The
events are ordered in the list by event_time. If the event
is placed before the end of the list, subsequent events are
removed from the list by marking them as 'removed' and
recording the time of removal. This allows efficient backup
of the state of the queue if a subsequent analog timestep
fails.
*/
void EVTqueue_output(
CKTcircuit *ckt,
int output_index,
int udn_index,
Evt_Output_Event_t *new_event,
double posted_time,
double event_time)
{
Evt_Output_Queue_t *output_queue;
Evt_Output_Event_t **here;
Evt_Output_Event_t *next;
Mif_Boolean_t splice;
NG_IGNORE(udn_index);
output_queue = &(ckt->evt->queue.output);
new_event->event_time = event_time;
new_event->posted_time = posted_time;
new_event->removed = MIF_FALSE;
if((output_queue->num_pending <= 0) ||
(event_time < output_queue->next_time))
output_queue->next_time = event_time;
splice = MIF_FALSE;
here = output_queue->current[output_index];
while(*here) {
if(event_time <= (*here)->event_time) {
splice = MIF_TRUE;
break;
}
here = &((*here)->next);
}
if(splice) {
next = *here;
*here = new_event;
new_event->next = next;
while(next) {
if(! next->removed) {
next->removed = MIF_TRUE;
next->removed_time = posted_time;
}
next = next->next;
}
}
else {
*here = new_event;
new_event->next = NULL;
}
if(! output_queue->modified[output_index]) {
output_queue->modified[output_index] = MIF_TRUE;
output_queue->modified_index[(output_queue->num_modified)++] =
output_index;
}
if(! output_queue->pending[output_index]) {
output_queue->pending[output_index] = MIF_TRUE;
output_queue->pending_index[(output_queue->num_pending)++] =
output_index;
}
}
EVTqueue_inst
This function places the specified inst event onto the inst
queue.
The linked list in the queue for the specified inst is
searched beginning at the current head of the pending events
to find the location at which to insert the new event. The
events are ordered in the list by event_time.
*/
void EVTqueue_inst(
CKTcircuit *ckt,
int inst_index,
double posted_time,
double event_time)
{
Evt_Inst_Queue_t *inst_queue;
Evt_Inst_Event_t **here;
Evt_Inst_Event_t *new_event;
Evt_Inst_Event_t *next;
Mif_Boolean_t splice;
inst_queue = &(ckt->evt->queue.inst);
if((inst_queue->num_pending <= 0) ||
(event_time < inst_queue->next_time))
inst_queue->next_time = event_time;
splice = MIF_FALSE;
here = inst_queue->current[inst_index];
while(*here) {
if(event_time == (*here)->event_time) {
return;
}
else if(event_time < (*here)->event_time) {
splice = MIF_TRUE;
break;
}
here = &((*here)->next);
}
if(inst_queue->free[inst_index]) {
new_event = inst_queue->free[inst_index];
inst_queue->free[inst_index] = new_event->next;
}
else {
new_event = TMALLOC(Evt_Inst_Event_t, 1);
}
new_event->event_time = event_time;
new_event->posted_time = posted_time;
if(splice) {
next = *here;
*here = new_event;
new_event->next = next;
}
else {
*here = new_event;
new_event->next = NULL;
}
if(! inst_queue->modified[inst_index]) {
inst_queue->modified[inst_index] = MIF_TRUE;
inst_queue->modified_index[(inst_queue->num_modified)++] =
inst_index;
}
if(! inst_queue->pending[inst_index]) {
inst_queue->pending[inst_index] = MIF_TRUE;
inst_queue->pending_index[(inst_queue->num_pending)++] =
inst_index;
}
}