www.pudn.com > geosteiner-3.1.zip > cpulimit.c
/*********************************************************************** File: cpulimit.c Rev: b-1 Date: 01/10/97 Copyright (c) 1993, 2001 by David M. Warme ************************************************************************ Routines to enforce CPU time limits. ************************************************************************ Modification Log: b-1: 01/10/97 warme : Split off from old_bs.c ************************************************************************/ #include "config.h" #include "steiner.h" #include/* * Global Routines */ bool decode_cpu_time_limit (char *, int32u *); void start_limiting_cpu_time (int32u); /* * External References */ /* none */ /* * Local Routines */ static RETSIGTYPE check_limit (int); static int32u cpu_time_limit; static int32u end_time; /* * This routine decodes an argument string that represents an amount of * CPU time. The time is the sum of a sequence of time groups. Each * time group is a sequence of decimal digits followed by an optional * letter defining units of minutes, hours, days, etc. * The regular expression accepted is: * * ([0-9]+([dhms][a-z]*)?)* */ bool decode_cpu_time_limit ( char * ap, int32u * limit ) { int32u total; int32u group; char c; *limit = 0; total = 0; c = *ap++; while (c NE '\0') { if ((c < '0') OR (c > '9')) { return (FALSE); } group = c - '0'; while (((c = *ap++) NE '\0') AND ('0' <= c) AND (c <= '9')) { group = (10 * group) + (c - '0'); } switch (c) { case 'd': group *= (24 * 60 * 60); break; case 'h': group *= (60 * 60); break; case 'm': group *= 60; break; case 's': break; case '\0': break; default: return (FALSE); } /* strip rest of unit name... */ while ((c > 0) AND ((c < '0') OR (c > '9'))) { c = *ap++; } total += group; } *limit = total; return (TRUE); } /* * This routine begins limiting CPU time starting right now. If the given * limit is ever exceeded, the process exits with an error message. */ void start_limiting_cpu_time ( int32u limit /* IN - maximum CPU seconds to permit. */ ) { int32u now; int32u then; if (limit > 0) { cpu_time_limit = limit; now = get_cpu_time (); then = now + limit * TICKS_PER_SEC; /* Record the time at which we should shut down... */ end_time = then; /* Schedule the first timer interrupt. */ check_limit (0); } } /* * This routine handles the "ALARM" signal, which goes off after a set * amount of *REAL* time. We check the CPU time usage -- if it has * exceeded the limit, we print a message and exit. Otherwise, we * reschedule another alarm signal. */ static RETSIGTYPE check_limit ( int sig ) { int32u now; int32u delta_seconds; now = get_cpu_time (); if (now >= end_time) { (void) printf ("\n\n%% ***** CPU time limit of %lu" " seconds exceeded *****\n", cpu_time_limit); exit (1); } delta_seconds = (end_time - now + TICKS_PER_SEC - 1) / TICKS_PER_SEC; signal (SIGALRM, check_limit); alarm (delta_seconds); }