473,390 Members | 1,207 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,390 software developers and data experts.

setjmp/longjmp and some table tennis

Hi,

I'm learning to use the setjmp/longjmp functions and still can't
really grasp what's going on here. I'd basically like to be able to
jump back and forth from (or to) two given functions.

Let's consider the following toy-example (yes, the example is stupid
but never mind...)

BEGIN CODE =====================
#include <stdlib.h>
#include <stdio.h>
#include <setjmp.h>

void wrapper();
void ping(jmp_buf, jmp_buf);
void pong(jmp_buf, jmp_buf);

int main() {
wrapper();
return 0;
}
void ping(jmp_buf ping_env, jmp_buf pong_env) {
printf("calling ping\n");
switch (setjmp(ping_env)) {
case 0:
printf("ping: case 0\n");
pong(ping_env, pong_env);
break;
case 1:
printf("ping: case 1\n");
longjmp(pong_env, 1);
break;
case 2:
printf("ping: case 2\n");
longjmp(pong_env, 2);
break;
default:
printf("ping: case default\n");
break;
}
printf("ping is done\n");
}
void pong(jmp_buf ping_env, jmp_buf pong_env) {
printf("\tcalling pong\n");
switch (setjmp(pong_env)) {
case 0:
printf("\tpong: case 0\n");
longjmp(ping_env, 1);
break;
case 1:
printf("\tpong: case 1\n");
longjmp(ping_env, 2);
break;
case 2:
printf("\tpong: case 2\n");
longjmp(ping_env, 3);
break;
default:
printf("\tpong: case default\n");
break;
}
printf("pong is done\n");
}
void wrapper() {
jmp_buf pong_env;
jmp_buf ping_env;
ping(ping_env, pong_env);
}
END CODE ========================

This code works OK if I make ping_env and pong_env static global
variables. However, when I try to pass them as parameters the code
crash with a "Bus error".

Any explanation as to why it crashes? (Well, I guess that's because
the jmp_buf variables passed as parameters are somehow not properly
restored, but I'm new to this so...)

And, even better, any advise on how to correct this while keeping the
intent of the program? (Yeah, I know any real-life application of this
pattern would yield pretty awful code but that's not the matter
here...)

Thanks,

nch

Feb 23 '07 #1
3 1872
In article <11**********************@q2g2000cwa.googlegroups. com>,
<no************@yahoo.comwrote:
>Hi,

I'm learning to use the setjmp/longjmp functions and still can't
really grasp what's going on here. I'd basically like to be able to
jump back and forth from (or to) two given functions.
Then setjmp/longjmp is the wrong tool for the job. You're only allowed
to longjmp back to a setjmp in a stack frame that's still live.

>And, even better, any advise on how to correct this while keeping the
intent of the program? (Yeah, I know any real-life application of this
pattern would yield pretty awful code but that's not the matter
here...)
You want coroutines. They're not directly supported by C (or, for
that matter, by a lot of other languages); there are ways to do it
using correct and portable C code, but they're all Rather Ugly and/or
quite limited.

If you don't mind giving up portability, using threads to fake it might
be the cleanest solution, even though they're kind of heavyweight for
something like this (and they'll take a bit of care to get right).
dave

--
Dave Vandervies dj******@csclub.uwaterloo.ca
Always assume that your code will need to be maintained -- and that the
next person to work on it is a homocidal maniac who knows where you live.
--Keith Thompson in comp.lang.c
Feb 23 '07 #2
Dave Vandervies writes:
You want coroutines. They're not directly supported by C (or, for
that matter, by a lot of other languages); there are ways to do it
using correct and portable C code, but they're all Rather Ugly and/or
quite limited.
In this case it's simple enough. Let ping() and pong return the value
to be passed to each other, and write a controlling function which calls
them.

For more complicated examples it gets uglier, yes. E.g. let ping() and
pong() fill a struct with a pointer to the next function to be called
and its arguments, and the controlling function would call via that
struct. Or set an integer representing what to do next, and write
the controlling function as a state machine.

--
Regards,
Hallvard
Feb 23 '07 #3

<no************@yahoo.comwrote in message
news:11**********************@q2g2000cwa.googlegro ups.com...
Hi,

I'm learning to use the setjmp/longjmp functions and still can't
really grasp what's going on here. I'd basically like to be able to
jump back and forth from (or to) two given functions.
<snip>
And, even better, any advise on how to correct this while keeping the
intent of the program? (Yeah, I know any real-life application of this
pattern would yield pretty awful code but that's not the matter
here...)
Don't use a screwdriver when a pair of pliers is called for.
Use something patterned like this:

typedef void (*Bouncer)( /*whatever needs passing*/ );

void ping( /*whatever needs passing*/ );
void pong( /*whatever needs passing*/ );
....
Bouncer next = NULL;
while (1) {
next = (next==ping) ? pong : ping;
(*next) (/*whatever needs passing*/ );
}
--
Fred L. Kleinschmidt
Boeing Associate Technical Fellow
Aero Stability and Controls Computing
Feb 23 '07 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Thomas Baruchel | last post by:
Hi, wondering about: func1: setjmp() ; func2(); func2: {FILE *f; f = fopen(); func3(); fclose(f)} func3 : if() longjmp; else return; Note that FILE *fis a local variable in func2.
12
by: Michael B Allen | last post by:
Should setjmp/longjmp really be used in a fast mundane ANSI C piece of code? Or is it frowned apon like goto? I have a need but I don't want to use something that is costly, isn't supported...
4
by: Jrferguson | last post by:
I have a C program that I am trying to port to a Motorola 68k based system. It makes use of setjmp and longjmp which are not supported by my C compiler. I understand the general principle behind...
5
by: candy | last post by:
hi all, Consider the following C code: void funct(){ }
20
by: JS | last post by:
When setjmp is called how can the if statement evaluate to true or false when setjmp only returns 0 or non-zero? struct pcb { void *(*start_routine) (void *); void *arg; jmp_buf state; int...
8
by: Zheng Da | last post by:
I wrote a simple one as follow: typedef struct __myjmp_buf { int efp; int epc; }myjmp_buf; int mysetjmp(myjmp_buf env) {
15
by: rover8898 | last post by:
Hello all, I used setjmp() in a recent of program of mine (it is not completed, so I have not the chance to test it out yet). I am not very profocient in C coding as are some of my co-workers....
4
by: nicho | last post by:
Could some knowledgable soul tell me if the following setjmp/longjmp structure will work from a logical standpoint ? The problem is that bar() needs to suspend processing and return control to...
5
by: Spiros Bousbouras | last post by:
In the following assume that a is int and env is of type jmp_buf a = setjmp(env) ; Is it legal ? It looks reasonable but it seems to violate what is mentioned under "Environmental limits" of...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.