While doing this tutorial http://www.thebox.myzen.co.uk/Tutorial/Merging_Code.html it struck me that a sort of simple cooperative task swapping routine could be written to replace delay().What would happen is that when called it would look at a list of functions that had called it and return to a function only when the passed delay value had timed out. Therefore you could have say two blinking light routines each calling this delayAndSwap() function and the two functions would do a sort of task swapping.

What is needed is access to the function return stack. It is easy enough in machine code but is there a way of getting this in C?

The calling routine can only pass the address of an entry point, so you can call a designated function. I have a version of delay that does what GM would like to do, but only one task at a time can call it (which makes it not very useful).

While doing this tutorial http://www.thebox.myzen.co.uk/Tutorial/Merging_Code.html it struck me that a sort of simple cooperative task swapping routine could be written to replace delay().What would happen is that when called it would look at a list of functions that had called it and return to a function only when the passed delay value had timed out. Therefore you could have say two blinking light routines each calling this delayAndSwap() function and the two functions would do a sort of task swapping.

What is needed is access to the function return stack. It is easy enough in machine code but is there a way of getting this in C?

You need multiple stacks to swap in this way (via a call - known as coroutines). Light-weight-thread basically means a stack, and can be cooperative (coroutines) or pre-emptive (switched on timer interrupts - more problematical). setjmp() and longjmp() can handle the return address to some extent IIRC, but you need a library to manage the stacks. In general the compiler has to understand what is going on too (setjmp/longjmp semantics should be understood by the compiler).

Stack switching itself is easy - save all registers to the current stack, switch stack pointer, then restore registers from the new stack and return. Somewhere you have to record information about which stack(s) to switch to when next switching, but this is usually a parameter of the coroutine call.http://en.wikipedia.org/wiki/Coroutine#Implementations_for_CSo yes, you need to manipulate the return values, but also the stack pointer, and need to set-aside space for each thread's stack

Yes I know all that. I can do it in machine code. I first did it in machine code back in 1978. However, if I am to do it in C I need access to the C stack where the return address is stored but it looks like I can't get it.

This reminded me of a piece of code I wrote a few months ago. I wanted to write a function: boolean every(long micros) , that would return true if micros microseconds had elapsed since last time it returned true, and false at all other times. So you could write for example: if(every(1000000))toggleLed(13); To discriminate between different calls to every in the same program I needed to know the return address to the caller, and I used __builtin_return_address(0) for that. There is __builtin_frame_address too which might be helpful.

(What I ended up doing with every was to use preprocessor metaprogramming to make every into a macro. Then I could use __COUNTER__ to discriminate between calls. Usage is now even simpler: every(1000000)toggleLed(13); This is probably the worst hack I have ever written, but for simple LED flashing it seems to work)

//usage: every(time) doSomething(); // time = period in microseconds// Be careful, this macro has a trailing if and can bite you. You have been warned!// This code guaranteed safe for use in life support systems, nuclear power stations// and large hadron colliders