1
0
Fork 0

Rewrote event.cxx in C++ as a class using STL for the internal event list

and run queue this removes the arbitrary list sizes and makes things much
more dynamic.  Because this is C++-classified we can now have multiple
event_tables if we'd ever want them.
This commit is contained in:
curt 1998-05-22 21:14:53 +00:00
parent cbdc65f55a
commit d093a9422b
3 changed files with 318 additions and 327 deletions

View file

@ -1,27 +1,25 @@
/************************************************************************** // event.cxx -- Flight Gear periodic event scheduler
* event.c -- Flight Gear periodic event scheduler //
* // Written by Curtis Olson, started December 1997.
* Written by Curtis Olson, started December 1997. //
* // Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
* Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com //
* // This program is free software; you can redistribute it and/or
* This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as
* modify it under the terms of the GNU General Public License as // published by the Free Software Foundation; either version 2 of the
* published by the Free Software Foundation; either version 2 of the // License, or (at your option) any later version.
* License, or (at your option) any later version. //
* // This program is distributed in the hope that it will be useful, but
* This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of
* WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details.
* General Public License for more details. //
* // You should have received a copy of the GNU General Public License
* You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software
* along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. //
* // $Id$
* $Id$ // (Log is kept at end of this file)
* (Log is kept at end of this file)
**************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -36,132 +34,38 @@
#endif #endif
#if defined( HAVE_WINDOWS_H ) && defined(__MWERKS__) #if defined( HAVE_WINDOWS_H ) && defined(__MWERKS__)
# include <windows.h> /* For Metrowerks environment */ # include <windows.h> // For Metrowerks environment
# include <winbase.h> /* There is no ANSI/MSL time function that */ # include <winbase.h> // There is no ANSI/MSL time function that
/* contains milliseconds */ // contains milliseconds
#endif #endif
#include <Debug/fg_debug.h> #include <Debug/fg_debug.h>
#include "event.hxx" #include "event.hxx"
#include "fg_time.hxx"
fgEVENT_MGR global_events;
#define MAX_EVENTS 100 /* size of event table */
#define MAX_RUN_QUEUE 100 /* size of run queue */
struct fgEVENT { // run a specified event
char description[256]; static void RunEvent(fgEVENT *e) {
void (*event)( void ); /* pointer to function */
int status; /* status flag */
long interval; /* interval in ms between each iteration of this event */
fg_timestamp last_run;
fg_timestamp current;
fg_timestamp next_run;
long cum_time; /* cumulative processor time of this event */
long min_time; /* time of quickest execution */
long max_time; /* time of slowest execution */
long count; /* number of times executed */
};
/* Event table */
struct fgEVENT events[MAX_EVENTS];
int event_ptr;
/* Run Queue */
int queue[MAX_RUN_QUEUE];
int queue_front;
int queue_end;
/* initialize the run queue */
void initq( void ) {
queue_front = queue_end = 0;
}
/* return queue empty status */
int emptyq( void ) {
if ( queue_front == queue_end ) {
return(1);
} else {
return(0);
}
}
/* return queue full status */
int fullq( void ) {
if ( (queue_end + 1) % MAX_RUN_QUEUE == queue_front ) {
return(1);
} else {
return(0);
}
}
/* add a member to the back of the queue */
void addq(int ptr) {
if ( !fullq() ) {
queue[queue_end] = ptr;
events[ptr].status = FG_EVENT_QUEUED;
queue_end = (queue_end + 1) % MAX_RUN_QUEUE;
} else {
printf("RUN QUEUE FULL!!!\n");
}
/* printf("Queued function %d (%d %d)\n", ptr, queue_front, queue_end); */
}
/* remove a member from the front of the queue */
int popq( void ) {
int ptr;
if ( emptyq() ) {
printf("PANIC: RUN QUEUE IS EMPTY!!!\n");
ptr = 0;
} else {
ptr = queue[queue_front];
/* printf("Popped position %d = %d\n", queue_front, ptr); */
queue_front = (queue_front + 1) % MAX_RUN_QUEUE;
}
return(ptr);
}
/* run a specified event */
void fgEventRun(int ptr) {
struct fgEVENT *e;
long duration; long duration;
e = &events[ptr];
printf("Running %s\n", e->description); printf("Running %s\n", e->description);
/* record starting time */ // record starting time
timestamp(&(e->last_run)); timestamp(&(e->last_run));
/* run the event */ // run the event
(*e->event)(); (*e->event)();
/* increment the counter for this event */ // increment the counter for this event
e->count++; e->count++;
/* update the event status */ // update the event status
e->status = FG_EVENT_READY; e->status = FG_EVENT_READY;
/* calculate duration and stats */ // calculate duration and stats
timestamp(&(e->current)); timestamp(&(e->current));
duration = timediff(&(e->last_run), &(e->current)); duration = timediff(&(e->last_run), &(e->current));
@ -175,189 +79,220 @@ void fgEventRun(int ptr) {
e->max_time = duration; e->max_time = duration;
} }
/* determine the next absolute run time */ // determine the next absolute run time
timesum(&(e->next_run), &(e->last_run), e->interval); timesum(&(e->next_run), &(e->last_run), e->interval);
} }
/* Initialize the scheduling subsystem */ // Constructor
void fgEventInit( void ) { fgEVENT_MGR::fgEVENT_MGR( void ) {
printf("Initializing event manager\n");
event_ptr = 0;
initq();
} }
/* Register an event with the scheduler, returns a pointer into the // Initialize the scheduling subsystem
* event table */ void fgEVENT_MGR::Init( void ) {
int fgEventRegister(char *desc, void (*event)( void ), int status, printf("Initializing event manager\n");
// clear event table
while ( event_table.size() ) {
event_table.pop_front();
}
// clear run queue
while ( run_queue.size() ) {
run_queue.pop_front();
}
}
// Register an event with the scheduler
void fgEVENT_MGR::Register(char *desc, void (*event)( void ), int status,
int interval) int interval)
{ {
struct fgEVENT *e; fgEVENT e;
e = &events[event_ptr];
printf("Registering event: %s\n", desc); printf("Registering event: %s\n", desc);
if ( strlen(desc) < 256 ) { if ( strlen(desc) < 256 ) {
strcpy(e->description, desc); strcpy(e.description, desc);
} else { } else {
strncpy(e->description, desc, 255); strncpy(e.description, desc, 255);
e->description[255] = '\0'; e.description[255] = '\0';
} }
e->event = event; e.event = event;
e->status = status; e.status = status;
e->interval = interval; e.interval = interval;
e->cum_time = 0; e.cum_time = 0;
e->min_time = 100000; e.min_time = 100000;
e->max_time = 0; e.max_time = 0;
e->count = 0; e.count = 0;
/* Actually run the event */ // Actually run the event
fgEventRun(event_ptr); RunEvent(&e);
event_ptr++; // Now add to event_table
event_table.push_back(e);
return(event_ptr - 1);
} }
/* Update the scheduling parameters for an event */ // Update the scheduling parameters for an event
void fgEventUpdate( void ) { void fgEVENT_MGR::Update( void ) {
} }
/* Delete a scheduled event */ // Delete a scheduled event
void fgEventDelete( void ) { void fgEVENT_MGR::Delete( void ) {
} }
/* Temporarily suspend scheduling of an event */ // Temporarily suspend scheduling of an event
void fgEventSuspend( void ) { void fgEVENT_MGR::Suspend( void ) {
} }
/* Resume scheduling and event */ // Resume scheduling and event
void fgEventResume( void ) { void fgEVENT_MGR::Resume( void ) {
} }
/* Dump scheduling stats */ // Dump scheduling stats
void fgEventPrintStats( void ) { void fgEVENT_MGR::PrintStats( void ) {
int i; deque < fgEVENT > :: iterator current = event_table.begin();
deque < fgEVENT > :: iterator last = event_table.end();
fgEVENT e;
if ( event_ptr > 0 ) {
printf("\n"); printf("\n");
printf("Event Stats\n"); printf("Event Stats\n");
printf("-----------\n"); printf("-----------\n");
for ( i = 0; i < event_ptr; i++ ) { while ( current != last ) {
e = *current++;
printf(" %-20s int=%.2fs cum=%ld min=%ld max=%ld count=%ld ave=%.2f\n", printf(" %-20s int=%.2fs cum=%ld min=%ld max=%ld count=%ld ave=%.2f\n",
events[i].description, e.description,
events[i].interval / 1000.0, e.interval / 1000.0,
events[i].cum_time, e.cum_time, e.min_time, e.max_time, e.count,
events[i].min_time, events[i].max_time, events[i].count, e.cum_time / (double)e.count);
events[i].cum_time / (double)events[i].count);
} }
printf("\n"); printf("\n");
} }
}
/* Add pending jobs to the run queue and run the job at the front of // Add pending jobs to the run queue and run the job at the front of
* the queue */ // the queue
void fgEventProcess( void ) { void fgEVENT_MGR::Process( void ) {
fg_timestamp current; fgEVENT *e_ptr;
int i; fg_timestamp cur_time;
unsigned int i, size;
fgPrintf(FG_EVENT, FG_DEBUG, "Processing events\n"); fgPrintf(FG_EVENT, FG_DEBUG, "Processing events\n");
/* get the current time */ // get the current time
timestamp(&current); timestamp(&cur_time);
fgPrintf(FG_EVENT, FG_DEBUG, " Current timestamp = %ld\n", current.seconds); fgPrintf( FG_EVENT, FG_DEBUG,
" Current timestamp = %ld\n", cur_time.seconds);
/* printf("Checking if anything is ready to move to the run queue\n"); */ // printf("Checking if anything is ready to move to the run queue\n");
/* see if anything else is ready to be placed on the run queue */ // see if anything else is ready to be placed on the run queue
for ( i = 0; i < event_ptr; i++ ) { size = event_table.size();
if ( events[i].status == FG_EVENT_READY ) { // while ( current != last ) {
for ( i = 0; i < size; i++ ) {
// e = *current++;
e_ptr = &event_table[i];
if ( e_ptr->status == FG_EVENT_READY ) {
fgPrintf(FG_EVENT, FG_DEBUG, fgPrintf(FG_EVENT, FG_DEBUG,
" Item %d, current %d, next run @ %ld\n", " Item %d, current %d, next run @ %ld\n",
i, current.seconds, events[i].next_run.seconds); i, cur_time.seconds, e_ptr->next_run.seconds);
if ( timediff(&current, &(events[i].next_run)) <= 0) { if ( timediff(&cur_time, &(e_ptr->next_run)) <= 0) {
addq(i); run_queue.push_back(e_ptr);
e_ptr->status = FG_EVENT_QUEUED;
} }
} }
} }
/* Checking to see if there is anything on the run queue */ // Checking to see if there is anything on the run queue
/* printf("Checking to see if there is anything on the run queue\n"); */ // printf("Checking to see if there is anything on the run queue\n");
if ( !emptyq() ) { if ( run_queue.size() ) {
/* printf("Yep, running it\n"); */ // printf("Yep, running it\n");
i = popq(); e_ptr = run_queue.front();
fgEventRun(i); run_queue.pop_front();
RunEvent(e_ptr);
} }
} }
/* $Log$ // Destructor
/* Revision 1.2 1998/04/25 22:06:33 curt fgEVENT_MGR::~fgEVENT_MGR( void ) {
/* Edited cvs log messages in source files ... bad bad bad! }
/*
* Revision 1.1 1998/04/24 00:52:26 curt
* Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H" void fgEventPrintStats( void ) {
* Fog color fixes. global_events.PrintStats();
* Separated out lighting calcs into their own file. }
*
* Revision 1.13 1998/04/18 04:14:08 curt
* Moved fg_debug.c to it's own library. // $Log$
* // Revision 1.3 1998/05/22 21:14:53 curt
* Revision 1.12 1998/04/09 18:40:13 curt // Rewrote event.cxx in C++ as a class using STL for the internal event list
* We had unified some of the platform disparate time handling code, and // and run queue this removes the arbitrary list sizes and makes things much
* there was a bug in timesum() which calculated a new time stamp based on // more dynamic. Because this is C++-classified we can now have multiple
* the current time stamp + offset. This hosed the periodic event processing // event_tables if we'd ever want them.
* logic because you'd never arrive at the time the event was scheduled for. //
* Sky updates and lighting changes are handled via this event mechanism so // Revision 1.2 1998/04/25 22:06:33 curt
* they never changed ... it is fixed now. // Edited cvs log messages in source files ... bad bad bad!
* //
* Revision 1.11 1998/04/03 22:12:55 curt // Revision 1.1 1998/04/24 00:52:26 curt
* Converting to Gnu autoconf system. // Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
* Centralized time handling differences. // Fog color fixes.
* // Separated out lighting calcs into their own file.
* Revision 1.10 1998/03/14 00:28:34 curt //
* replaced a printf() with an fgPrintf(). // Revision 1.13 1998/04/18 04:14:08 curt
* // Moved fg_debug.c to it's own library.
* Revision 1.9 1998/01/31 00:43:44 curt //
* Added MetroWorks patches from Carmen Volpe. // Revision 1.12 1998/04/09 18:40:13 curt
* // We had unified some of the platform disparate time handling code, and
* Revision 1.8 1998/01/27 00:48:05 curt // there was a bug in timesum() which calculated a new time stamp based on
* Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message // the current time stamp + offset. This hosed the periodic event processing
* system and commandline/config file processing code. // logic because you'd never arrive at the time the event was scheduled for.
* // Sky updates and lighting changes are handled via this event mechanism so
* Revision 1.7 1998/01/19 19:27:19 curt // they never changed ... it is fixed now.
* Merged in make system changes from Bob Kuehne <rpk@sgi.com> //
* This should simplify things tremendously. // Revision 1.11 1998/04/03 22:12:55 curt
* // Converting to Gnu autoconf system.
* Revision 1.6 1998/01/19 18:40:39 curt // Centralized time handling differences.
* Tons of little changes to clean up the code and to remove fatal errors //
* when building with the c++ compiler. // Revision 1.10 1998/03/14 00:28:34 curt
* // replaced a printf() with an fgPrintf().
* Revision 1.5 1998/01/06 01:20:27 curt //
* Tweaks to help building with MSVC++ // Revision 1.9 1998/01/31 00:43:44 curt
* // Added MetroWorks patches from Carmen Volpe.
* Revision 1.4 1997/12/31 17:46:50 curt //
* Tweaked fg_time.c to be able to use ftime() instead of gettimeofday() // Revision 1.8 1998/01/27 00:48:05 curt
* // Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
* Revision 1.3 1997/12/30 22:22:42 curt // system and commandline/config file processing code.
* Further integration of event manager. //
* // Revision 1.7 1998/01/19 19:27:19 curt
* Revision 1.2 1997/12/30 20:47:58 curt // Merged in make system changes from Bob Kuehne <rpk@sgi.com>
* Integrated new event manager with subsystem initializations. // This should simplify things tremendously.
* //
* Revision 1.1 1997/12/30 04:19:22 curt // Revision 1.6 1998/01/19 18:40:39 curt
* Initial revision. // Tons of little changes to clean up the code and to remove fatal errors
* // when building with the c++ compiler.
*/ //
// Revision 1.5 1998/01/06 01:20:27 curt
// Tweaks to help building with MSVC++
//
// Revision 1.4 1997/12/31 17:46:50 curt
// Tweaked fg_time.c to be able to use ftime() instead of gettimeofday()
//
// Revision 1.3 1997/12/30 22:22:42 curt
// Further integration of event manager.
//
// Revision 1.2 1997/12/30 20:47:58 curt
// Integrated new event manager with subsystem initializations.
//
// Revision 1.1 1997/12/30 04:19:22 curt
// Initial revision.

View file

@ -1,27 +1,25 @@
/************************************************************************** // event.hxx -- Flight Gear periodic event scheduler
* event.hxx -- Flight Gear periodic event scheduler //
* // Written by Curtis Olson, started December 1997.
* Written by Curtis Olson, started December 1997. //
* // Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
* Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com //
* // This program is free software; you can redistribute it and/or
* This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as
* modify it under the terms of the GNU General Public License as // published by the Free Software Foundation; either version 2 of the
* published by the Free Software Foundation; either version 2 of the // License, or (at your option) any later version.
* License, or (at your option) any later version. //
* // This program is distributed in the hope that it will be useful, but
* This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of
* WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details.
* General Public License for more details. //
* // You should have received a copy of the GNU General Public License
* You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software
* along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. //
* // $Id$
* $Id$ // (Log is kept at end of this file)
* (Log is kept at end of this file)
**************************************************************************/
#ifndef _EVENT_HXX #ifndef _EVENT_HXX
@ -33,63 +31,115 @@
#endif #endif
#include <deque.h> // STL double ended queue
#include <list.h> // STL list
#include "fg_time.hxx"
#define FG_EVENT_SUSP 0 #define FG_EVENT_SUSP 0
#define FG_EVENT_READY 1 #define FG_EVENT_READY 1
#define FG_EVENT_QUEUED 2 #define FG_EVENT_QUEUED 2
/* Initialize the scheduling subsystem */ typedef struct {
void fgEventInit( void ); char description[256];
/* Register an event with the scheduler, returns a pointer into the void (*event)( void ); // pointer to function
* event table */ int status; // status flag
int fgEventRegister(char *desc, void (*event)( void ), int status,
long interval; // interval in ms between each iteration of this event
fg_timestamp last_run;
fg_timestamp current;
fg_timestamp next_run;
long cum_time; // cumulative processor time of this event
long min_time; // time of quickest execution
long max_time; // time of slowest execution
long count; // number of times executed
} fgEVENT;
class fgEVENT_MGR {
// Event table
deque < fgEVENT > event_table;
// Run Queue
list < fgEVENT * > run_queue;
public:
// Constructor
fgEVENT_MGR ( void );
// Initialize the scheduling subsystem
void Init( void );
// Register an event with the scheduler
void Register(char *desc, void (*event)( void ), int status,
int interval); int interval);
/* Update the scheduling parameters for an event */ // Update the scheduling parameters for an event
void fgEventUpdate( void ); void Update( void );
/* Delete a scheduled event */ // Delete a scheduled event
void fgEventDelete( void ); void Delete( void );
/* Temporarily suspend scheduling of an event */ // Temporarily suspend scheduling of an event
void fgEventSuspend( void ); void Suspend( void );
/* Resume scheduling and event */ // Resume scheduling and event
void fgEventResume( void ); void Resume( void );
/* Dump scheduling stats */ // Dump scheduling stats
void PrintStats( void );
// Add pending jobs to the run queue and run the job at the front
// of the queue
void Process( void );
// Destructor
~fgEVENT_MGR ( void );
};
// Wrapper to dump scheduling stats
void fgEventPrintStats( void ); void fgEventPrintStats( void );
/* Add pending jobs to the run queue and run the job at the front of extern fgEVENT_MGR global_events;
* the queue */
void fgEventProcess( void );
#endif /* _EVENT_HXX */ #endif // _EVENT_HXX
/* $Log$ // $Log$
/* Revision 1.1 1998/04/24 00:52:26 curt // Revision 1.2 1998/05/22 21:14:54 curt
/* Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H" // Rewrote event.cxx in C++ as a class using STL for the internal event list
/* Fog color fixes. // and run queue this removes the arbitrary list sizes and makes things much
/* Separated out lighting calcs into their own file. // more dynamic. Because this is C++-classified we can now have multiple
/* // event_tables if we'd ever want them.
* Revision 1.4 1998/04/21 17:01:43 curt //
* Fixed a problems where a pointer to a function was being passed around. In // Revision 1.1 1998/04/24 00:52:26 curt
* one place this functions arguments were defined as ( void ) while in another // Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
* place they were defined as ( int ). The correct answer was ( int ). // Fog color fixes.
* // Separated out lighting calcs into their own file.
* Prepairing for C++ integration. //
* // Revision 1.4 1998/04/21 17:01:43 curt
* Revision 1.3 1998/01/22 02:59:43 curt // Fixed a problems where a pointer to a function was being passed around. In
* Changed #ifdef FILE_H to #ifdef _FILE_H // one place this functions arguments were defined as ( void ) while in another
* // place they were defined as ( int ). The correct answer was ( int ).
* Revision 1.2 1998/01/19 18:40:39 curt //
* Tons of little changes to clean up the code and to remove fatal errors // Prepairing for C++ integration.
* when building with the c++ compiler. //
* // Revision 1.3 1998/01/22 02:59:43 curt
* Revision 1.1 1997/12/30 04:19:22 curt // Changed #ifdef FILE_H to #ifdef _FILE_H
* Initial revision. //
* // Revision 1.2 1998/01/19 18:40:39 curt
*/ // Tons of little changes to clean up the code and to remove fatal errors
// when building with the c++ compiler.
//
// Revision 1.1 1997/12/30 04:19:22 curt
// Initial revision.

View file

@ -85,7 +85,7 @@ typedef struct {
extern fgTIME cur_time_params; extern fgTIME cur_time_params;
typedef struct fg_timestamp_t { typedef struct {
long seconds; long seconds;
long millis; long millis;
} fg_timestamp; } fg_timestamp;
@ -115,6 +115,12 @@ void fgTimeUpdate(fgFLIGHT *f, fgTIME *t);
// $Log$ // $Log$
// Revision 1.5 1998/05/22 21:14:54 curt
// Rewrote event.cxx in C++ as a class using STL for the internal event list
// and run queue this removes the arbitrary list sizes and makes things much
// more dynamic. Because this is C++-classified we can now have multiple
// event_tables if we'd ever want them.
//
// Revision 1.4 1998/04/28 01:22:17 curt // Revision 1.4 1998/04/28 01:22:17 curt
// Type-ified fgTIME and fgVIEW. // Type-ified fgTIME and fgVIEW.
// //