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);
}
´´´

Reply via email to