Jump to content
  • Advertisement
Sign in to follow this  
HellRiZZer

Temporary return?

This topic is 4830 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
Advertisement
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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 :)

Share this post


Link to post
Share on other sites
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++ );
}
}

Share this post


Link to post
Share on other sites
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 class
class task
{
public:
virtual ~task() { }
virtual bool operator () () = 0;
};

// a simple task, printing numbers from 1 to max
class 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 tasks
class 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 :)

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!