Thread overview
interrupting a function
Nov 17, 2018
Alex
Nov 17, 2018
Paul Backus
Nov 17, 2018
Alex
Nov 26, 2018
Alex
November 17, 2018
I wished I never come across the nightmare of such a question. And maybe, there is still a bug in my code, which I'm not aware of (which I strongly suppose :/ ).
But nevertheless, and for learning purposes, assume I have something like this:

´´´
auto foo(/*input params*/)
{
    //some long calculations, depending on input params.
}

void main()
{
    foo;
}
´´´

It can happen, that the input params are correct, however, the calculation lasts too long. Is there a way, to measure the execution time of foo (á la benchmark) and then, if some execution time limit is exceeded to interrupt the calculation? At best, with a flag, whether foo ended normally or because of the interruption.
November 17, 2018
On Saturday, 17 November 2018 at 06:19:25 UTC, Alex wrote:
> It can happen, that the input params are correct, however, the calculation lasts too long. Is there a way, to measure the execution time of foo (á la benchmark) and then, if some execution time limit is exceeded to interrupt the calculation? At best, with a flag, whether foo ended normally or because of the interruption.

You could run the calculation in another thread and use std.concurrency.receiveTimeout [1] to stop waiting for the result after a certain amount of time.

[1] https://dlang.org/phobos/std_concurrency.html#.receiveTimeout
November 17, 2018
On Saturday, 17 November 2018 at 08:17:36 UTC, Paul Backus wrote:
>
> You could run the calculation in another thread and use std.concurrency.receiveTimeout [1] to stop waiting for the result after a certain amount of time.
>
> [1] https://dlang.org/phobos/std_concurrency.html#.receiveTimeout

Ah... yes. Thanks!
November 26, 2018
On Saturday, 17 November 2018 at 08:17:36 UTC, Paul Backus wrote:
> You could run the calculation in another thread and use std.concurrency.receiveTimeout [1] to stop waiting for the result after a certain amount of time.

Ok... would you say the following is a feasible alternative?

´´´
import std.experimental.all;
import core.thread;

auto assumeNoGC(T) (T t) if (isFunctionPointer!T || isDelegate!T)
{
    enum attrs = functionAttributes!T | FunctionAttribute.nogc;
    return cast(SetFunctionAttributes!(T, functionLinkage!T, attrs)) t;
}

struct D
{
	size_t d;
	static S s;
}
struct S
{
	size_t dummy;
	D[] data;
}

struct Model
{
	auto ref s()
	{
		return D.s;
	}

	size_t counter;

	void run() @nogc
	{
		do
		{
			debug
			{
				"I'm running".writeln;
				writeln(s.data.length);
				writeln(s.dummy);
				
			}
			
			// some heavy work, which is nogc
			Thread.sleep(1.seconds);

			assumeNoGC((){
				yield(); // is stack change a nogc action?
			})();

			counter++;
		}while(counter < 10);
	}
}

Fiber composed;

auto myCall()
{
	return composed.call;
}

void main()
{
	Model m;
	composed = new Fiber( &m.run );

	D.s.data.length = 4;
	D.s.dummy = 42;

	import std.datetime.stopwatch : Duration, benchmark;
	Duration res;
	bool abort;
	while(composed.state != Fiber.State.TERM)
	{
		writeln(res == Duration.zero);
		res += benchmark!(((myCall)))(1).front;
		writeln(m.counter);
		writeln(composed.state);
		writeln(res);
		writeln(res > 5.seconds);
		if(res > 5.seconds)
		{
			abort = true;
			break;
		}
	}
	assert(abort);
}
´´´