/***************************************************************************** * 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; }