Initial revision.
This commit is contained in:
parent
09b8076bca
commit
b89d27f083
3 changed files with 399 additions and 1 deletions
|
@ -26,7 +26,7 @@
|
|||
|
||||
TARGET = libTime.a
|
||||
|
||||
CFILES = fg_time.c fg_timer.c sunpos.c
|
||||
CFILES = event.c fg_time.c fg_timer.c sunpos.c
|
||||
OFILES = $(CFILES:.c=.o)
|
||||
|
||||
|
||||
|
@ -56,6 +56,9 @@ clean:
|
|||
|
||||
include depend
|
||||
|
||||
event.o:
|
||||
$(CC) $(CFLAGS) -c event.c -o $@
|
||||
|
||||
fg_time.o:
|
||||
$(CC) $(CFLAGS) -c fg_time.c -o $@
|
||||
|
||||
|
@ -68,6 +71,9 @@ sunpos.o:
|
|||
|
||||
#---------------------------------------------------------------------------
|
||||
# $Log$
|
||||
# Revision 1.14 1997/12/30 04:19:22 curt
|
||||
# Initial revision.
|
||||
#
|
||||
# Revision 1.13 1997/09/22 14:44:22 curt
|
||||
# Continuing to try to align stars correctly.
|
||||
#
|
||||
|
|
329
Time/event.c
Normal file
329
Time/event.c
Normal file
|
@ -0,0 +1,329 @@
|
|||
/**************************************************************************
|
||||
* event.c -- Flight Gear periodic event scheduler
|
||||
*
|
||||
* Written by Curtis Olson, started December 1997.
|
||||
*
|
||||
* Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id$
|
||||
* (Log is kept at end of this file)
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef USE_FTIME
|
||||
# include <sys/timeb.h> /* for ftime() and struct timeb */
|
||||
#else
|
||||
# include <sys/time.h> /* for get/setitimer, gettimeofday, struct timeval */
|
||||
#endif USE_FTIME
|
||||
|
||||
|
||||
#include "event.h"
|
||||
|
||||
|
||||
#define MAX_EVENTS 100 /* size of event table */
|
||||
#define MAX_RUN_QUEUE 100 /* size of run queue */
|
||||
|
||||
|
||||
struct fgEVENT {
|
||||
char description[256];
|
||||
|
||||
void (*event)(); /* pointer to function */
|
||||
int status; /* status flag */
|
||||
|
||||
long interval; /* interval in ms between each iteration of this event */
|
||||
|
||||
#ifdef USE_FTIME
|
||||
struct timeb last_run; /* absolute time for last run */
|
||||
struct timeb current; /* current time */
|
||||
struct timeb next_run; /* absolute time for next run */
|
||||
#else
|
||||
struct timeval last_run; /* absolute time for last run */
|
||||
struct timeval current; /* current time */
|
||||
struct timeval next_run; /* absolute time for next run */
|
||||
struct timezone tz;
|
||||
#endif /* USE_FTIME */
|
||||
|
||||
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() {
|
||||
queue_front = queue_end = 0;
|
||||
}
|
||||
|
||||
|
||||
/* return queue empty status */
|
||||
int emptyq() {
|
||||
if ( queue_front == queue_end ) {
|
||||
return(1);
|
||||
} else {
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* return queue full status */
|
||||
int fullq() {
|
||||
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() {
|
||||
int ptr;
|
||||
|
||||
if ( !emptyq() ) {
|
||||
ptr = queue[queue_front];
|
||||
/* printf("Popped position %d = %d\n", queue_front, ptr); */
|
||||
queue_front = (queue_front + 1) % MAX_RUN_QUEUE;
|
||||
return(ptr);
|
||||
} else {
|
||||
printf("PANIC: RUN QUEUE IS EMPTY!!!\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* run a specified event */
|
||||
void fgEventRun(int ptr) {
|
||||
struct fgEVENT *e;
|
||||
long duration;
|
||||
|
||||
e = &events[ptr];
|
||||
|
||||
/* record starting time */
|
||||
#ifdef USE_FTIME
|
||||
ftime(&e->last_run);
|
||||
#else
|
||||
gettimeofday(&e->last_run, &e->tz);
|
||||
#endif /* USE_FTIME */
|
||||
|
||||
/* run the event */
|
||||
(*e->event)();
|
||||
|
||||
/* increment the counter for this event */
|
||||
e->count++;
|
||||
|
||||
/* update the event status */
|
||||
e->status = FG_EVENT_READY;
|
||||
|
||||
/* calculate duration and stats */
|
||||
#ifdef USE_FTIME
|
||||
ftime(&e->current);
|
||||
duration = 1000 * (e->current.time - e->last_run.time) +
|
||||
(e->current.millitm - e->last_run.millitm);
|
||||
#else
|
||||
gettimeofday(&e->current, &e->tz);
|
||||
duration = 1000000 * (e->current.tv_sec - e->last_run.tv_sec) +
|
||||
(e->current.tv_usec - e->last_run.tv_usec);
|
||||
duration /= 1000; /* convert back to milleseconds */
|
||||
#endif /* USE_FTIME */
|
||||
|
||||
e->cum_time += duration;
|
||||
|
||||
if ( duration < e->min_time ) {
|
||||
e->min_time = duration;
|
||||
}
|
||||
|
||||
if ( duration > e->max_time ) {
|
||||
e->max_time = duration;
|
||||
}
|
||||
|
||||
/* determine the next absolute run time */
|
||||
#ifdef USE_FTIME
|
||||
e->next_run.time = e->last_run.time +
|
||||
(e->last_run.millitm + e->interval) / 1000;
|
||||
e->next_run.millitm = (e->last_run.millitm + e->interval) % 1000;
|
||||
#else
|
||||
e->next_run.tv_sec = e->last_run.tv_sec +
|
||||
(e->last_run.tv_usec + e->interval * 1000) / 1000000;
|
||||
e->next_run.tv_usec = (e->last_run.tv_usec + e->interval * 1000) % 1000000;
|
||||
#endif /* USE_FTIME */
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the scheduling subsystem */
|
||||
void fgEventInit() {
|
||||
event_ptr = 0;
|
||||
initq();
|
||||
}
|
||||
|
||||
|
||||
/* Register an event with the scheduler, returns a pointer into the
|
||||
* event table */
|
||||
int fgEventRegister(char *desc, void (*event)(), int status, int interval) {
|
||||
struct fgEVENT *e;
|
||||
|
||||
e = &events[event_ptr];
|
||||
|
||||
if ( strlen(desc) < 256 ) {
|
||||
strcpy(e->description, desc);
|
||||
} else {
|
||||
strncpy(e->description, desc, 255);
|
||||
e->description[255] = '\0';
|
||||
}
|
||||
|
||||
e->event = event;
|
||||
e->status = status;
|
||||
e->interval = interval;
|
||||
|
||||
e->cum_time = 0;
|
||||
e->min_time = 100000;
|
||||
e->max_time = 0;
|
||||
e->count = 0;
|
||||
|
||||
/* Actually run the event */
|
||||
fgEventRun(event_ptr);
|
||||
|
||||
event_ptr++;
|
||||
|
||||
return(event_ptr - 1);
|
||||
}
|
||||
|
||||
|
||||
/* Update the scheduling parameters for an event */
|
||||
void fgEventUpdate() {
|
||||
}
|
||||
|
||||
|
||||
/* Delete a scheduled event */
|
||||
void fgEventDelete() {
|
||||
}
|
||||
|
||||
|
||||
/* Temporarily suspend scheduling of an event */
|
||||
void fgEventSuspend() {
|
||||
}
|
||||
|
||||
|
||||
/* Resume scheduling and event */
|
||||
void fgEventResume() {
|
||||
}
|
||||
|
||||
|
||||
/* Dump scheduling stats */
|
||||
void fgEventPrintStats() {
|
||||
int i;
|
||||
|
||||
printf("Event Stats\n");
|
||||
|
||||
for ( i = 0; i < event_ptr; i++ ) {
|
||||
printf(" %s cum=%d min=%d max=%d count=%d ave=%.2f\n",
|
||||
events[i].description, events[i].cum_time, events[i].min_time,
|
||||
events[i].max_time, events[i].count,
|
||||
events[i].cum_time / (double)events[i].count);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Add pending jobs to the run queue and run the job at the front of
|
||||
* the queue */
|
||||
void fgEventProcess() {
|
||||
#ifdef USE_FTIME
|
||||
struct timeb current;
|
||||
#else
|
||||
struct timeval current;
|
||||
struct timezone tz;
|
||||
#endif /* USE_FTIME */
|
||||
int i;
|
||||
|
||||
/* printf("Processing events\n"); */
|
||||
|
||||
/* get the current time */
|
||||
#ifdef USE_FTIME
|
||||
ftime(¤t);
|
||||
#else
|
||||
gettimeofday(¤t, &tz);
|
||||
#endif /* USE_FTIME */
|
||||
|
||||
/* 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 */
|
||||
for ( i = 0; i < event_ptr; i++ ) {
|
||||
if ( events[i].status == FG_EVENT_READY ) {
|
||||
#ifdef USE_FTIME
|
||||
if ( current.time > events[i].next_run.time ) {
|
||||
addq(i);
|
||||
} else if ( (current.time == events[i].next_run.time) &&
|
||||
(current.millitm >= events[i].next_run.millitm) ) {
|
||||
addq(i);
|
||||
}
|
||||
#else
|
||||
if ( current.tv_sec > events[i].next_run.tv_sec ) {
|
||||
addq(i);
|
||||
} else if ( (current.tv_sec == events[i].next_run.tv_sec) &&
|
||||
(current.tv_usec >= events[i].next_run.tv_usec) ) {
|
||||
addq(i);
|
||||
}
|
||||
|
||||
#endif /* USE_FTIME */
|
||||
}
|
||||
}
|
||||
|
||||
/* Checking to see if there is anything on the run queue */
|
||||
/* printf("Checking to see if there is anything on the run queue\n"); */
|
||||
if ( !emptyq() ) {
|
||||
/* printf("Yep, running it\n"); */
|
||||
i = popq();
|
||||
fgEventRun(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* $Log$
|
||||
/* Revision 1.1 1997/12/30 04:19:22 curt
|
||||
/* Initial revision.
|
||||
/*
|
||||
*/
|
63
Time/event.h
Normal file
63
Time/event.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
/**************************************************************************
|
||||
* event.h -- Flight Gear periodic event scheduler
|
||||
*
|
||||
* Written by Curtis Olson, started December 1997.
|
||||
*
|
||||
* Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id$
|
||||
* (Log is kept at end of this file)
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#define FG_EVENT_SUSP 0
|
||||
#define FG_EVENT_READY 1
|
||||
#define FG_EVENT_QUEUED 2
|
||||
|
||||
|
||||
/* Initialize the scheduling subsystem */
|
||||
void fgEventInit();
|
||||
|
||||
/* Register an event with the scheduler, returns a pointer into the
|
||||
* event table */
|
||||
int fgEventRegister(char *desc, void (*event)(), int status, int interval);
|
||||
|
||||
/* Update the scheduling parameters for an event */
|
||||
void fgEventUpdate();
|
||||
|
||||
/* Delete a scheduled event */
|
||||
void fgEventDelete();
|
||||
|
||||
/* Temporarily suspend scheduling of an event */
|
||||
void fgEventSuspend();
|
||||
|
||||
/* Resume scheduling and event */
|
||||
void fgEventResume();
|
||||
|
||||
/* Dump scheduling stats */
|
||||
void fgEventPrintStats();
|
||||
|
||||
/* Add pending jobs to the run queue and run the job at the front of
|
||||
* the queue */
|
||||
void fgEventProcess();
|
||||
|
||||
|
||||
/* $Log$
|
||||
/* Revision 1.1 1997/12/30 04:19:22 curt
|
||||
/* Initial revision.
|
||||
/*
|
||||
*/
|
Loading…
Reference in a new issue