/*****************************************************************************
* File: sys_evpool.c
*
*
* Notice:
* (C) Copyright 1999, 2000 ROX Software, Inc.
* All rights reserved.
*
* Model Compiler: MC3020 V1.3.0
*
* Warnings:
* !!! THIS IS AN AUTO-GENERATED FILE. PLEASE DO NOT EDIT. !!!
****************************************************************************/
#include <stdlib.h>
#include "sys_init.h"
#include "e_mechs.h"
#include "e_events.h"
#include "e_objset.h"
#include "sys_user_co.h"
/* Include header(s) of domain level events union. */
#include "A_events.h"
#include "EXP_events.h"
/*****************************************************************************
* Structure: SystemOoaEvents_u
* 'Super-union' of all OOA events in the system. For translation patterns
* which can not accept dynamic memory allocation for OOA events, this union
* is used to predetermine the maximum size of any OOA event in the system.
****************************************************************************/
union SystemOoaEvents_u
{
OoaEvent_t mc_event_base;
A_DomainEvents_u mc_events_in_domain_A;
EXP_DomainEvents_u mc_events_in_domain_EXP;
};
typedef union SystemOoaEvents_u SystemOoaEvents_u;
/*****************************************************************************
* Provide anchor declaration for front and back of list of events.
****************************************************************************/
typedef struct OoaEventQueue_s OoaEventQueue_s;
struct OoaEventQueue_s
{
OoaEvent_t * head, * tail;
};
/*****************************************************************************
* Pre-allocated memory pool for OOA events.
****************************************************************************/
static SystemOoaEvents_u aSG_ooa_event_pool[ SYS_MAX_OOA_EVENTS ];
static OoaEvent_t * pSG_free_event_list = (OoaEvent_t *) 0;
/*****************************************************************************
* Link the event skeleton nodes together on the free list ready
* for allocation.
****************************************************************************/
void
InitializeOoaEventPool()
{
unsigned int i;
/* String events together into a singly linked list. */
pSG_free_event_list = (OoaEvent_t *) &aSG_ooa_event_pool[ 0 ];
for ( i = 0; i < SYS_MAX_OOA_EVENTS; i++ )
{
aSG_ooa_event_pool[ i ].mc_event_base.next = (OoaEvent_t *) &(aSG_ooa_event_pool[ i + 1 ]);
aSG_ooa_event_pool[ i ].mc_event_base.prev = (OoaEvent_t *) 0;
}
aSG_ooa_event_pool[ SYS_MAX_OOA_EVENTS - 1 ].mc_event_base.next = (OoaEvent_t *) 0;
}
/*****************************************************************************
* Escher_AllocateOoaEvent
* Note: event_size unused, reserved for future use, eliminated for now.
****************************************************************************/
OoaEvent_t *
Escher_AllocateOoaEvent()
{
OoaEvent_t * event;
if ( ! pSG_free_event_list )
{
UserEventFreeListEmptyCallout(); /* Bad news! No more events. */
}
else
{
event = pSG_free_event_list; /* Grab front of the free list. */
pSG_free_event_list = event->next; /* Unlink from front of free list. */
ClearOoaEventFlags( event );
}
return event;
}
/*****************************************************************************
* Escher_NewOoaEvent
* Allocate the event and initialize the base attributes.
****************************************************************************/
OoaEvent_t *
Escher_NewOoaEvent( const void * const destination,
const OoaEventConstant_t * const event_info )
{
OoaEvent_t * event = Escher_AllocateOoaEvent();
SetEventTargetInstance( event, destination );
SetEventDestDomainNumber( event, event_info->destination_domain_number );
SetEventDestObjectNumber( event, event_info->destination_object_number );
SetOoaEventNumber( event, event_info->event_number );
SetOoaEventFlags( event, event_info->event_flags );
SetOoaEventPriority( event, event_info->priority );
return event;
}
/*****************************************************************************
* Escher_DeleteOoaEvent
****************************************************************************/
void
Escher_DeleteOoaEvent( void * event )
{
if ( event != 0 )
{
((OoaEvent_t *) event)->next = pSG_free_event_list;
pSG_free_event_list = (OoaEvent_t *) event;
}
}
static OoaEventQueue_s sSG_non_self_event_queue;
/*****************************************************************************
* Zero the anchor points for the non- self-directed event queue.
****************************************************************************/
void
InitializeOoaNonSelfEventQueue()
{
sSG_non_self_event_queue.head = (OoaEvent_t *) 0;
sSG_non_self_event_queue.tail = (OoaEvent_t *) 0;
}
/*****************************************************************************
* Send an event to the instance queue. Use priority where applicable.
*
* The following table summarizes the construction of events as
* expected in Escher. For each type of object (or pseudo-object)
* that may be the source or target of an event, the expected
* value of the source and destination handles in the event are
* given.
*
* object type | as event source | as destination
* ------------+---------------------+----------------------
* instance | handle | handle
* assigner | manufactured handle | 0
* creator | manufactured handle | 0
* init | manufactured handle | cannot be destination
* FBO | manufactured handle | cannot be destination
*
****************************************************************************/
void
Escher_SendEvent( OoaEvent_t * event )
{
/* Insert event into empty event queue. */
if ( sSG_non_self_event_queue.tail == (OoaEvent_t *) 0 )
{
sSG_non_self_event_queue.head = event; /* first in queue */
sSG_non_self_event_queue.tail = event; /* last in queue */
event->next = (OoaEvent_t *) 0;
event->prev = (OoaEvent_t *) 0;
}
else
/* No priority, append to end of queue. */
if ( event->priority == 0 )
{
event->next = (OoaEvent_t *) 0; /* input at tail end */
event->prev = sSG_non_self_event_queue.tail;
sSG_non_self_event_queue.tail->next = event; /* non empty */
sSG_non_self_event_queue.tail = event; /* tail points to last */
}
else
/* Priority event, insert at proper position. */
{
OoaEvent_t * e = sSG_non_self_event_queue.tail;
/* Find slot before which to insert our new arrival. */
/* Break from the loop before the event we must follow. */
while ( e != (OoaEvent_t *) 0 )
{
if ( event->priority <= e->priority )
break;
if ( GetEventTargetInstance( event ) == GetEventTargetInstance(e) ) {
if ( GetEventSendingInstance( event ) == GetEventSendingInstance(e) ) {
if ( GetEventTargetInstance( event ) != 0 )
break;
else
/* Creator or assigner with no target instance handle. */
/* We must interrogate the object and domain numbers. */
if ( GetEventDestObjectNumber( event ) == GetEventDestObjectNumber( e ) )
if ( GetEventDestDomainNumber( event ) == GetEventDestDomainNumber( e ) )
break;
}
}
e = e->prev;
}
if ( e == (OoaEvent_t *) 0 )
{
/* Slot not found, insert after head. */
e = sSG_non_self_event_queue.head;
event->prev = (OoaEvent_t *) 0;
event->next = e;
e->prev = event;
sSG_non_self_event_queue.head = event;
}
else
{
/* Slot found, insert before. */
event->prev = e;
event->next = e->next;
e->next = event;
if ( event->next != (OoaEvent_t *) 0 )
event->next->prev = event;
if ( sSG_non_self_event_queue.tail == e )
sSG_non_self_event_queue.tail = event;
}
}
}
/*****************************************************************************
* Drag an event from the instance directed queue if there is one. This
* routine also serves as the IsQueueEmpty routine. A null return code
* indicates that the queue is empty. Otherwise the handle to the
* event will be returned.
****************************************************************************/
OoaEvent_t *
DequeueOoaNonSelfEvent()
{
OoaEvent_t * event;
/* Assign the event from the head of the queue. */
event = sSG_non_self_event_queue.head;
/* If the list is not empty, bump the head. */
if ( event != (OoaEvent_t *) 0 )
{
sSG_non_self_event_queue.head = event->next;
/* If empty, nullify tail. Link prev pointers. */
if ( sSG_non_self_event_queue.head == (OoaEvent_t *) 0 )
sSG_non_self_event_queue.tail = (OoaEvent_t *) 0;
else
sSG_non_self_event_queue.head->prev = (OoaEvent_t *) 0;
}
return event;
}
/*****************************************************************************
****************************************************************************/
static OoaEventQueue_s sSG_self_event_queue;
/*****************************************************************************
* Zero the anchor points for the self-directed event queue.
****************************************************************************/
void
InitializeOoaSelfEventQueue()
{
sSG_self_event_queue.head = (OoaEvent_t *) 0;
sSG_self_event_queue.tail = (OoaEvent_t *) 0;
}
/*****************************************************************************
* Send an event to the self queue. No prioritization occurs on
* this queue.
****************************************************************************/
void
Escher_SendSelfEvent( OoaEvent_t * event )
{
event->next = (OoaEvent_t *) 0;
/* Append the event to the tail end of the queue. */
/* No need to maintain prev pointers for self directed events. */
if ( sSG_self_event_queue.tail == (OoaEvent_t *) 0 )
sSG_self_event_queue.head = event;
else
sSG_self_event_queue.tail->next = event;
sSG_self_event_queue.tail = event;
}
/*****************************************************************************
* Drag an event from the self queue if there is one. This routine
* also serves as the IsQueueEmpty routine. A null return code
* indicates that the queue is empty. Otherwise the handle to the
* event will be returned.
****************************************************************************/
OoaEvent_t *
DequeueOoaSelfEvent()
{
OoaEvent_t * event;
/* Assign the event from the head of the queue. */
event = sSG_self_event_queue.head;
/* If the list is not empty, bump the head. */
if ( event != (OoaEvent_t *) 0 )
{
sSG_self_event_queue.head = event->next; /* bump */
/* If empty, nullify tail. No need to maintain prev pointers
for the self queue. They are not used. */
if ( sSG_self_event_queue.head == (OoaEvent_t *) 0 )
sSG_self_event_queue.tail = (OoaEvent_t *) 0;
}
return event;
}