lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

> Basically, I chop up the available stack by recursing down it, planting
> a setjmp() at my chosen intervals and filling in an array of jmp_bufs as I
> go. I can then longjmp() to any one I choose from my scheduling kernel, but
> of course there's no protection to prevent me exceeding my self-imposed
> stack size in each co-routine, so recursion within individual co-routines
> whould require some caution. 

Neat, but nasty.

> Am I exploiting a feature that pure ANSI C does
> not necessarily support? 

Yes. The description of longjmp in ISO 7.6.2 reads in part: "if the
function containing the invocation of the setjmp macro has terminated
execution in the interim, the behaviour is undefined". A footnote to
"terminated execution" reads "For example, by executing a return
statement or because another longjmp call has caused a transfer to a
setjmp invocation in a function earlier in the set of nested calls".
Now, footnotes aren't part of the standard, but you aren't going to
win that one.

In summary, you can use longjmp to jump to an earlier function, but
not a later one.

>         int thread_tag = setjmp(jbuf_array[stacks_remaining]);

Also, this use of setjmp is not allowed by the environmental
constraint in 7.6.1. It must appear as an expression
statements in one of the following forms:

	(void) setjmp(...);
and as an expression controlling a selection or iteration
statement in tne of the following forms
	integral-constant-expression rel-op setjmp(...)
	setjmp(...) rel-op integral-constant-expression 
	! setjmp(...)

Notice in particular that there is no way to determine in general the
value returned by a setjmp function. (Although if you know it must be
one of a limited number of values, you can determine the value using a
suitable selection statement.)

Strictly conformant ISO C is very limiting.

Alan Watson