Temporary return?

Started by
13 comments, last by Inmate2993 18 years, 7 months ago
Hi all, I've been about all the Google, but can't find an article that talks about temporary exit from the function (using assembly or something else). Do you remember what it is called, better yet, what's the link to it? Thanks.
Advertisement
I'm only guessing here but setjmp/longjmp are probably what you want.
Do note that they really doesn't play well with C++ constructs like ctors/dtors.
HardDrop - hard link shell extension."Tread softly because you tread on my dreams" - Yeats
No, I'm talking about temporarily exiting a function at some stage and then returning to it. Basically it has something to do with advanced C++ or extreme programming, I'm just not sure. I read an article on it somewhere, I searched CodeProject and CodeGuru, but couldn't find it.
Here's "My Horrible Attempt At Hacking Together What You Described"

int function(){  static int exitstage = 0;  // declare all local variables static    switch (exitstage)  {    case 0:      // Initialize local variables      if (whatever) return 1;      exitstage = 1;    case 1:      // Do some real code here... might "return" if you need to       if (whatever) return 2;      exitstage = 2;    case 2:      // More code... whatever.  }    exitstage = 0;  return 0;}void main(){  while (function());}


But it's not reentrant, and you have to manually do the funky while-call style. :D

You could potentially replace the static variables with a caller-allocated state object that retains the exitstage and local variables:

int function(StateObject state){  switch (state.exitstage)  {    // same as above  }  state.exitstage = 0;    return useful_return_value_here;}void main(){  int retval;  StateObject state();  do { retval = function(state); } while (state.exitstage);}


Good luck preventing anyone else looking at the code from puking.


There are plenty of ways to do this kind of thing in assembly, many of which will probably confuse the hell out of a C++ compiler if you try them. The problem is that you have to save/restore your function parameters/local variables on the stack since it's just not going to work if you try to leave them intact.
Well... duh..
What I'm trying to do is to make a function kind-of like a task. For example, if that function does lots of calculations, then it'd hog the CPU when called and will grab the CPU resources that are required by higher priority procedures. So, what I'm trying to do is to create some kind of a task manager that will call a function and say "here's how many CPU cycles you have" and it will go until that or approximate to that amount.
Maybe it's a stupid idea in today' powerful world of CPUs, but I'm just curious if you can do that within a function in some other way than you've just described.

Thanks anyway for trying to help. Accounted for :)
Mmm.. my first urge is to start a new thread for the lengthy calculation.
Otherwise, I would just write something like this pseudo-code:
void lengthCalculation( int maxMilliSeconds ){   static int offset = 0;   int maxTime = getCurrentMilliSeconds() + maxMilliSeconds;   while( (offset < maxFooBars) && (getCurrentMilliSeconds() < maxTime) )   {      calculateFooBar( offset++ );   }}
Coroutines in C.
You may want to use actual threads though.
Sounds like you need a fiber enriched diet.
HardDrop - hard link shell extension."Tread softly because you tread on my dreams" - Yeats
A kernel/task system using co-operative multitasking can be done quite nicely in C++ using functors (objects that have their operator() overloaded so that they can be called like functions). This is a much better way to maintain state between calls than local static variables, because each instance of the same task class encapsulates its own state and is thus fully re-entrant. A small example:

#include <list>#include <iostream>// task base classclass task{ public:  virtual ~task() { }  virtual bool operator () () = 0;};// a simple task, printing numbers from 1 to maxclass counter : public task{ public:  counter(int max) :    c(0), max(max)  {  }  bool operator () ()  {    std::cout << ++c;    return c != max;  } private:  int c;  const int max;};// kernel handles running multiple tasksclass kernel{ public:  void add(task *t)  {    tasks.push_back(t);  }  bool run()  {    // while there are tasks left to run    while(!tasks.empty())    {      std::list<task *>::iterator i = tasks.begin(), e = tasks.end();      while(i != e)      {        // call each task in turn - if returns false, it is finished        // and will be removed from the list        if(!(**i)())          i = tasks.erase(i);        else          ++i;      }    }  } private:  std::list<task *> tasks;};int main(){  kernel k;  counter ctr(10);  k.add(&ctr);  k.run();}


A more elaborate system would probably use boost::function and its friends for more genericity, and possibly some scheme for passing arguments/messages to the tasks. That'll be left as an excercise to the reader :)
I also remember seeing something like this.

It was a set of asm functions that allowed you to suspend a function, then when you next called the function it would continue from the suspend statement.

It was complicated and I didn't understand the asm.

Does anyone have any idea where he could find it?

This topic is closed to new replies.

Advertisement