]> git.mxchange.org Git - flightgear.git/blob - Time/event.cxx
Edited cvs log messages in source files ... bad bad bad!
[flightgear.git] / Time / event.cxx
1 /**************************************************************************
2  * event.c -- Flight Gear periodic event scheduler
3  *
4  * Written by Curtis Olson, started December 1997.
5  *
6  * Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of the
11  * License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  *
22  * $Id$
23  * (Log is kept at end of this file)
24  **************************************************************************/
25
26
27 #ifdef HAVE_CONFIG_H
28 #  include <config.h>
29 #endif
30
31 #include <string.h>
32 #include <stdio.h>
33
34 #ifdef HAVE_STDLIB_H
35 #include <stdlib.h>
36 #endif
37
38 #if defined( HAVE_WINDOWS_H ) && defined(__MWERKS__)
39 #  include <windows.h>   /* For Metrowerks environment */
40 #  include <winbase.h>   /* There is no ANSI/MSL time function that */
41                          /* contains milliseconds */
42 #endif
43
44 #include <Debug/fg_debug.h>
45
46 #include "event.hxx"
47 #include "fg_time.hxx"
48
49
50
51 #define MAX_EVENTS 100    /* size of event table */
52 #define MAX_RUN_QUEUE 100 /* size of run queue */
53
54
55 struct fgEVENT {
56     char description[256];
57
58     void (*event)( void );  /* pointer to function */
59     int status;       /* status flag */
60
61     long interval;    /* interval in ms between each iteration of this event */
62
63     fg_timestamp last_run;
64     fg_timestamp current;
65     fg_timestamp next_run;
66
67     long cum_time;    /* cumulative processor time of this event */
68     long min_time;    /* time of quickest execution */
69     long max_time;    /* time of slowest execution */
70     long count;       /* number of times executed */
71 };
72
73
74 /* Event table */
75 struct fgEVENT events[MAX_EVENTS];
76 int event_ptr;
77
78
79 /* Run Queue */
80 int queue[MAX_RUN_QUEUE];
81 int queue_front;
82 int queue_end;
83
84
85 /* initialize the run queue */
86 void initq( void ) {
87     queue_front = queue_end = 0;
88 }
89
90
91 /* return queue empty status */
92 int emptyq( void ) {
93     if ( queue_front == queue_end ) {
94         return(1);
95     } else {
96         return(0);
97     }
98 }
99
100
101 /* return queue full status */
102 int fullq( void ) {
103     if ( (queue_end + 1) % MAX_RUN_QUEUE == queue_front ) {
104         return(1);
105     } else {
106         return(0);
107     }
108 }
109
110
111 /* add a member to the back of the queue */
112 void addq(int ptr) {
113     if ( !fullq() ) {
114         queue[queue_end] = ptr;
115         events[ptr].status = FG_EVENT_QUEUED;
116
117         queue_end = (queue_end + 1) % MAX_RUN_QUEUE;
118     } else {
119         printf("RUN QUEUE FULL!!!\n");
120     }
121
122     /* printf("Queued function %d (%d %d)\n", ptr, queue_front, queue_end); */
123 }
124
125
126 /* remove a member from the front of the queue */
127 int popq( void ) {
128     int ptr;
129
130     if ( emptyq() ) {
131         printf("PANIC:  RUN QUEUE IS EMPTY!!!\n");
132         ptr = 0;
133     } else {
134         ptr = queue[queue_front];
135         /* printf("Popped position %d = %d\n", queue_front, ptr); */
136         queue_front = (queue_front + 1) % MAX_RUN_QUEUE;
137     }
138
139     return(ptr);
140 }
141
142
143 /* run a specified event */
144 void fgEventRun(int ptr) {
145     struct fgEVENT *e;
146     long duration;
147
148     e = &events[ptr];
149     
150     printf("Running %s\n", e->description);
151
152     /* record starting time */
153     timestamp(&(e->last_run));
154
155     /* run the event */
156     (*e->event)();
157
158     /* increment the counter for this event */
159     e->count++;
160
161     /* update the event status */
162     e->status = FG_EVENT_READY;
163
164     /* calculate duration and stats */
165     timestamp(&(e->current));
166     duration = timediff(&(e->last_run), &(e->current));
167
168     e->cum_time += duration;
169
170     if ( duration < e->min_time ) {
171         e->min_time = duration;
172     }
173
174     if ( duration > e->max_time ) {
175         e->max_time = duration;
176     }
177
178     /* determine the next absolute run time */
179     timesum(&(e->next_run), &(e->last_run), e->interval);
180 }
181
182
183 /* Initialize the scheduling subsystem */
184 void fgEventInit( void ) {
185     printf("Initializing event manager\n");
186     event_ptr = 0;
187     initq();
188 }
189
190
191 /* Register an event with the scheduler, returns a pointer into the
192  * event table */
193 int fgEventRegister(char *desc, void (*event)( void ), int status, 
194                     int interval)
195 {
196     struct fgEVENT *e;
197
198     e = &events[event_ptr];
199
200     printf("Registering event: %s\n", desc);
201
202     if ( strlen(desc) < 256 ) {
203         strcpy(e->description, desc);
204     } else {
205         strncpy(e->description, desc, 255);
206         e->description[255] = '\0';
207     }
208
209     e->event = event;
210     e->status = status;
211     e->interval = interval;
212
213     e->cum_time = 0;
214     e->min_time = 100000;
215     e->max_time = 0;
216     e->count = 0;
217
218     /* Actually run the event */
219     fgEventRun(event_ptr);
220
221     event_ptr++;
222
223     return(event_ptr - 1);
224 }
225
226
227 /* Update the scheduling parameters for an event */
228 void fgEventUpdate( void ) {
229 }
230
231
232 /* Delete a scheduled event */
233 void fgEventDelete( void ) {
234 }
235
236
237 /* Temporarily suspend scheduling of an event */
238 void fgEventSuspend( void ) {
239 }
240
241
242 /* Resume scheduling and event */
243 void fgEventResume( void ) {
244 }
245
246
247 /* Dump scheduling stats */
248 void fgEventPrintStats( void ) {
249     int i;
250
251     if ( event_ptr > 0 ) {
252         printf("\n");
253         printf("Event Stats\n");
254         printf("-----------\n");
255
256         for ( i = 0; i < event_ptr; i++ ) {
257             printf("  %-20s  int=%.2fs cum=%ld min=%ld max=%ld count=%ld ave=%.2f\n",
258                    events[i].description, 
259                    events[i].interval / 1000.0,
260                    events[i].cum_time, 
261                    events[i].min_time, events[i].max_time, events[i].count, 
262                    events[i].cum_time / (double)events[i].count);
263         }
264         printf("\n");
265     }
266 }
267
268
269 /* Add pending jobs to the run queue and run the job at the front of
270  * the queue */
271 void fgEventProcess( void ) {
272     fg_timestamp current;
273     int i;
274
275     fgPrintf(FG_EVENT, FG_DEBUG, "Processing events\n");
276     
277     /* get the current time */
278     timestamp(&current);
279
280     fgPrintf(FG_EVENT, FG_DEBUG, "  Current timestamp = %ld\n", current.seconds);
281
282     /* printf("Checking if anything is ready to move to the run queue\n"); */
283
284     /* see if anything else is ready to be placed on the run queue */
285     for ( i = 0; i < event_ptr; i++ ) {
286         if ( events[i].status == FG_EVENT_READY ) {
287             fgPrintf(FG_EVENT, FG_DEBUG, 
288                      "  Item %d, current %d, next run @ %ld\n", 
289                      i, current.seconds, events[i].next_run.seconds);
290             if ( timediff(&current, &(events[i].next_run)) <= 0) {
291                 addq(i);
292             }
293         }
294     }
295
296     /* Checking to see if there is anything on the run queue */
297     /* printf("Checking to see if there is anything on the run queue\n"); */
298     if ( !emptyq() ) {
299         /* printf("Yep, running it\n"); */
300         i = popq();
301         fgEventRun(i);
302     }
303 }
304
305
306 /* $Log$
307 /* Revision 1.2  1998/04/25 22:06:33  curt
308 /* Edited cvs log messages in source files ... bad bad bad!
309 /*
310  * Revision 1.1  1998/04/24 00:52:26  curt
311  * Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
312  * Fog color fixes.
313  * Separated out lighting calcs into their own file.
314  *
315  * Revision 1.13  1998/04/18 04:14:08  curt
316  * Moved fg_debug.c to it's own library.
317  *
318  * Revision 1.12  1998/04/09 18:40:13  curt
319  * We had unified some of the platform disparate time handling code, and
320  * there was a bug in timesum() which calculated a new time stamp based on
321  * the current time stamp + offset.  This hosed the periodic event processing
322  * logic because you'd never arrive at the time the event was scheduled for.
323  * Sky updates and lighting changes are handled via this event mechanism so
324  * they never changed ... it is fixed now.
325  *
326  * Revision 1.11  1998/04/03 22:12:55  curt
327  * Converting to Gnu autoconf system.
328  * Centralized time handling differences.
329  *
330  * Revision 1.10  1998/03/14 00:28:34  curt
331  * replaced a printf() with an fgPrintf().
332  *
333  * Revision 1.9  1998/01/31 00:43:44  curt
334  * Added MetroWorks patches from Carmen Volpe.
335  *
336  * Revision 1.8  1998/01/27 00:48:05  curt
337  * Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
338  * system and commandline/config file processing code.
339  *
340  * Revision 1.7  1998/01/19 19:27:19  curt
341  * Merged in make system changes from Bob Kuehne <rpk@sgi.com>
342  * This should simplify things tremendously.
343  *
344  * Revision 1.6  1998/01/19 18:40:39  curt
345  * Tons of little changes to clean up the code and to remove fatal errors
346  * when building with the c++ compiler.
347  *
348  * Revision 1.5  1998/01/06 01:20:27  curt
349  * Tweaks to help building with MSVC++
350  *
351  * Revision 1.4  1997/12/31 17:46:50  curt
352  * Tweaked fg_time.c to be able to use ftime() instead of gettimeofday()
353  *
354  * Revision 1.3  1997/12/30 22:22:42  curt
355  * Further integration of event manager.
356  *
357  * Revision 1.2  1997/12/30 20:47:58  curt
358  * Integrated new event manager with subsystem initializations.
359  *
360  * Revision 1.1  1997/12/30 04:19:22  curt
361  * Initial revision.
362  *
363  */