dymm@b.cs.wvu.wvnet.edu (David Dymm) (03/08/89)
I would like to write an interrupt handling mechanism in 'C' to work in the following way: 1) Set up the signal facility: signal (SIGALRM, alarm_handler) 2) Set the alarm: ualarm (100000, 0) <== This will send a signal after 100,0000 microseconds. 3) The interrupt handler "alarm_handler" is called with the signal mechanism when the alarm timer times out. Let's call "location A" the place where we were in the code when we were interrupted by the timer. When "alarm_handler" has finished its local processing, I do NOT want to return control back to where the interrupt occurred!!!! Instead, I want to "longjmp" to another function in the program. When that function has completed its work, I want to return to "location A". The question is: How do I return to "location A" ??? I have looked at the "sigstack" mechanism, and also at the definitions for "sigcontext" and "sigstack" in "signal.h". But I do not see how to put this all together to accomplish my task. The system saves the state of the process on the signal stack when "signal" causes control to jump to "alarm_handler". How do I get at that information AND more importantly, how do I use that information to accomplish my task. Any ideas??? David Dymm Software Engineer USMAIL: Bell Atlantic Knowledge Systems, 145 Fayette Street, Morgantown, WV 26505 PHONE: 304 291-9898 (8:30-4:30 EST) USENET: {allegra,bellcore, cadre,idis,psuvax1}!pitt!wvucsb!dymm INTERNET: dymm@b.cs.wvu.wvnet.edu
alan@earwax.OZ (Alan J Peakall ) (03/10/89)
In article <318@h.cs.wvu.wvnet.edu>, dymm@b.cs.wvu.wvnet.edu (David Dymm) writes: > > I would like to write an interrupt handling mechanism > in 'C' to work in the following way: > > 1) Set up the signal facility: > > signal (SIGALRM, alarm_handler) > > 2) Set the alarm: > > ualarm (100000, 0) <== This will send a signal after > 100,0000 microseconds. > > 3) The interrupt handler "alarm_handler" is called with > the signal mechanism when the alarm timer times out. > Let's call "location A" the place where we were in > the code when we were interrupted by the timer. > > When "alarm_handler" has finished its local processing, > I do NOT want to return control back to where the > interrupt occurred!!!! > Instead, I want to "longjmp" to another function in the > program. When that function has completed its work, > I want to return to "location A". > > > The question is: How do I return to "location A" ??? > > I have looked at the "sigstack" mechanism, and also at > the definitions for "sigcontext" and "sigstack" in "signal.h". > But I do not see how to put this all together to accomplish > my task. The system saves the state of the process on the > signal stack when "signal" causes control to jump to > "alarm_handler". How do I get at that information AND more > importantly, how do I use that information to accomplish > my task. > > Any ideas??? If you are on an architecture on which <int>s and <void *>s are freely convertible and the usual implementation of <setjmp> obtains (ie jmp_buf declared as #define _JBLEN 10 /* or some other number */ typedef int jmp_buf[_JBLEN]; ) the following should work: /* handler.c -- immediate interrupt handler */ #include <setjmp.h> extern jmp_buf jmp_buf_in_other_function; int alarm_handler(int signo) { static jmp_buf recover; int returnval; /* assumed non-zero */ /* local processing */ ; if (!(returnval = setjmp(recover))) longjmp(jmp_buf_in_other_function, (int) recover); /* to auxiliary function */ else return returnval; /* to location 'A" */ } /* otherfunction.c -- supplementary interrupt handling & whatever else */ #include <setjmp.h> jmp_buf jmp_buf_in_other_function; void other_function() { int *recover; /* when invoked abnormally holds recover point */ int returnval; /* computed in this case - assumed non-zero */ if (recover = (int *) setjmp(jmp_buf_in_other_function)) { /* further processing for interrupt */ longjmp(recover, returnval); } else { /* usual processing */ } } this will be marginally less efficient than the use of <sigcontext> but considerably more portable, as the latter is not machine independent even within a given UNIX implementation let alone portable to all strains of UNIX-like systems. The <setjmp> implementation on which the above solution relies is more widely supported and even for those cases where the above does not work exactly as given, it is more readable (and thus more easily modifiable) than code that references details of the raw hardware itself.