12
Example program
- #include <sys/select.h>
- #include <stdlib.h>
- #include <strings.h>
- #include <signal.h>
- #include <errno.h>
- #include <time.h>
- #include <getopt.h>
- #include <errno.h>
- #include "scheduler.h"
- #include "task.h"
- #include "debug.h"
- #include "shell.h"
- #if defined( DEBUG )
- int debug = 0;
- #endif
- struct _tictac {
- shell shell;
- scheduler sched;
- task t1, t2, t3;
- } tictac;
- static int tic_tac_is_started( ) {
- return tictac.t1 && tictac.t2 && task_isqueued( tictac.t1 ) && task_isqueued( tictac.t2 );
- }
- static void tic_tac( char *s ) {
- time_t clock = time( (time_t *)0 );
- struct tm *tm = localtime( &clock );
- fprintf( stdout, "\007%s", s ); /* beep */
- fprintf( stdout, "%02d:%02d:%02d\n", tm->tm_hour, tm->tm_min, tm->tm_sec );
- fflush( stdout );
- }
- static void tic_tac_start( int period, int count ) {
- if ( !tic_tac_is_started() ) {
- time_t now = time( 0 );
- task t1 = tictac.t1, t2 = tictac.t2;
- /* lazy init */
- if ( !t1 )
- tictac.t1 = t1 = task_new( "TIC", 0, 0, 0, (void (*)( void * ))tic_tac, "<tic>" );
- if ( !t2 )
- tictac.t2 = t2 = task_new( "TAC", 0, 0, 0, (void (*)( void * ))tic_tac, "<tac>" );
- task_setattime( t1, now + period);
- task_setattime( t2, now + (2 * period));
- task_setperiod( t1, (2 * period)), task_setcount( t1, count );
- task_setperiod( t2, (2 * period)), task_setcount( t2, count );
- scheduler_addtask( tictac.sched, t1 );
- scheduler_addtask( tictac.sched, t2 );
- }
- }
- static void tic_tac_stop( char *reason ) {
- if ( tic_tac_is_started() ) {
- scheduler_rmtask( tictac.sched, tictac.t1 );
- scheduler_rmtask( tictac.sched, tictac.t2 );
- /* if interrupted, check for a queued stop */
- if ( tictac.t3 && task_isqueued( tictac.t3 ) )
- scheduler_rmtask( tictac.sched, tictac.t3 );
- if ( reason ) {
- fprintf( stdout, "%s\n", reason );
- fflush( stdout );
- }
- }
- }
- static void tic_tac_handle_signal( int sig ) {
- signal( sig, tic_tac_handle_signal ); /* catch again */
- tic_tac_stop( "<interrupted>");
- }
- static void cmd_start( int argc, char **argv ) {
- int period = 1, count = 0; /* every sec forever */
- switch( argc ) {
- case 3:
- count = atoi( argv[ 2 ] );
- /* fall thru */
- case 2:
- period = atoi( argv[ 1 ] );
- if ( period == 0 )
- period = 1;
- break;
- case 1:
- default:
- break;
- }
- tic_tac_start( period, count );
- }
- static void cmd_stop( int argc, char **argv ) {
- int delay = 0; /* kill by default */
- time_t now = time( 0 );
- switch( argc ) {
- case 2:
- delay = atoi( argv[ 1 ] );
- break;
- case 1:
- default:
- break;
- }
- if ( tictac.t3 && task_isqueued( tictac.t3 )) /* being stopped */
- scheduler_rmtask( tictac.sched, tictac.t3 );
- if ( !tictac.t3 )
- tictac.t3 = task_new( "STOP", 0, 0, 0, (void (*)( void * ))tic_tac_stop, "<stopped>" );
- task_setattime( tictac.t3, now + delay );
- scheduler_addtask( tictac.sched, tictac.t3 );
- }
- static void cmd_quit( int argc, char **argv ) {
- exit( 0 );
- }
- #if defined( DEBUG )
- #include "debug.h"
- static void cmd_debug( int argc, char **argv ) {
- switch ( argc ) {
- case 2:
- debug = atoi( argv[ 1 ] );
- break;
- case 1:
- fprintf( stdout, "%i\n", debug );
- break;
- default:
- fprintf( stderr, "%s [level]\n", argv[ 0 ] );
- break;
- }
- }
- #endif
- void main_loop( ) {
- fd_set read_fds;
- int n_fds = 1;
- struct timeval time_out, *tp = 0;
- time_t next_time;
- long delay = 0L;
- for ( ;; ) { /* forever */
- FD_ZERO( &read_fds );
- FD_SET( 0, &read_fds );
- switch( select( n_fds, &read_fds, 0, 0, tp )) {
- case -1: /* trouble */
- if( errno != EINTR )
- exit( 1 );
- break;
- case 0: /* time out */
- break;
- default: /* event */
- if( FD_ISSET( 0, &read_fds ))
- shell_input( tictac.shell, 0 );
- break;
- }
- /* anything else to do ? */
- if( (next_time = scheduler_run( tictac.sched )) ) {
- /* wake up for next job on schedule */
- if( (delay = next_time - time( (time_t *)0 )) < 0 )
- delay = 0; /* just to be sure */
- ONDEBUG1( printf( "[delay=%ld]\n", delay ));
- time_out.tv_sec = delay;
- time_out.tv_usec = 0L;
- tp = &time_out;
- }
- else
- tp = 0;
- }
- }
- int main( int argc, char **argv ) {
- extern int opterr;
- int c;
- tictac.shell = shell_new( );
- tictac.sched = scheduler_new( );
- opterr = 0;
- #if defined( DEBUG )
- while ( (c = getopt( argc, argv, "D:" )) != -1 )
- #else
- while ( (c = getopt( argc, argv, "" )) != -1 )
- #endif
- switch ( c ) {
- #if defined( DEBUG )
- case 'D':
- debug = atoi( optarg );
- break;
- #endif
- case '?':
- default:
- #if defined( DEBUG )
- fprintf( stderr, "%s [-D level]\n", argv[ 0 ] );
- #else
- fprintf( stderr, "%s\n", argv[ 0 ] );
- #endif
- exit( 1 );
- }
- shell_addcmd( tictac.shell, "start", "start [period] [count]", cmd_start );
- shell_addcmd( tictac.shell, "stop", "stop [delay]", cmd_stop );
- #if defined( DEBUG )
- shell_addcmd( tictac.shell, "debug", "debug [level]", cmd_debug );
- #endif
- shell_addcmd( tictac.shell, "quit", "quit | exit", cmd_quit );
- shell_addcmd( tictac.shell, "exit", "exit | quit", cmd_quit );
- /* catch ^C */
- signal( SIGINT, tic_tac_handle_signal );
- #if defined( DEBUG )
- setbuf( stdout, 0 );
- #endif
- main_loop( );
- }
To compile the program:
$ make tictac
gcc -Wall -O -fstrength-reduce -finline-functions -fomit-frame-pointer -c list.c
gcc -Wall -O -fstrength-reduce -finline-functions -fomit-frame-pointer -c shell.c
gcc -Wall -O -fstrength-reduce -finline-functions -fomit-frame-pointer -c task.c
gcc -Wall -O -fstrength-reduce -finline-functions -fomit-frame-pointer -c scheduler.c
gcc -Wall -O -fstrength-reduce -finline-functions -fomit-frame-pointer -c dump.c
ar rc libctk.a list.o shell.o task.o scheduler.o dump.o
gcc -Wall -O -fstrength-reduce -finline-functions -fomit-frame-pointer -c tictac.c
gcc tictac.o -o tictac libctk.a -lreadline
Test the program:
$ ./tictac
help
start [period] [count]
stop [delay]
quit | exit
exit | quit
start 1 2
10:14:23
10:14:24
10:14:25
10:14:26
quit
Comments