AW: [Oberon] precise specification of single remaining difficulty

Stauber Sven Philipp staubesv at student.ethz.ch
Thu Sep 21 18:41:29 CEST 2006


Hi,
 
The reason why the program below doesn't work is that "The conditions inside an object instance are re-evaluated whenever some activity leaves a protected block inside the same object instance." [Active Oberon Language Report, p. 10]
 
Note: Modules are considered to be singleton object instances. 
 
All the threads will increment the threadsdone variable, but the AWAIT statement won't notice that, because its condition is not re-evaluated, since the threadsdone variable is set in an exclusive region of a thread object, not in an exclusive region of the module.
 
To make it work, introduce a procedure
 
PROCEDURE IncThreadsDone;
BEGIN {EXCLUSIVE}
    INC(threadsdone);
END IncThreadsDone;
 
and call this instead of directly altering the threadsdone variable in the thread object instances. That way, the condition is set in the same object instance as the AWAIT statement waits for it (=module)
 
Regards,
Sven Stauber

________________________________

Von: oberon-bounces at lists.inf.ethz.ch im Auftrag von Søren Renner
Gesendet: Mi 20.09.2006 16:59
An: oberon at lists.inf.ethz.ch
Betreff: [Oberon] precise specification of single remaining difficulty



MODULE srThreadDemo;
IMPORT srBase, AosActive, DebugLog;

TYPE thread=OBJECT
VAR
        I: INTEGER;
       
PROCEDURE&init(i:INTEGER);
BEGIN
        I:=i;
END init;
       
BEGIN{ACTIVE, PRIORITY(AosActive.Normal)}
        REPEAT
                BEGIN{EXCLUSIVE}       
                        AWAIT(flag[I]);
                        INC(threadsdone);
                        flag[I]:=FALSE;
                END;
                DebugLog.Int(threadsdone,4);   
                DebugLog.String("threads done");
        UNTIL FALSE;
END thread;

VAR
        threads: ARRAY 10 OF thread;
        flag: ARRAY 10 OF BOOLEAN;
        gothreads: BOOLEAN;
        i: INTEGER;
        threadsdone: INTEGER;

PROCEDURE go*;
VAR
     i:INTEGER;
BEGIN
        BEGIN{EXCLUSIVE}       
                threadsdone:=0;
                FOR i := 0 TO 9 DO
                        flag[i]:=TRUE
                END;
                DebugLog.String("go go little threads. which thread will win? . . .");
                AWAIT(threadsdone=10)
        END;
        DebugLog.String("well, so much for those threads i guess"); (* NEVER
REACHED! *)
END go;

PROCEDURE loadmodule*;
END loadmodule;

BEGIN
        BEGIN{EXCLUSIVE}       
                gothreads:=FALSE
        END;
        FOR i := 0 TO 9 DO
                NEW(threads[i],i);
                DebugLog.String("sprawning thread "); DebugLog.Int(i,4); DebugLog.Ln;
        END;
        go;
END srThreadDemo.

srThreadDemo.go:

DebugLog output:

P1.218 srThreadDemo.$$[208]> sprawning thread

P1.218 srThreadDemo.$$[223]>    0

P0.218 srThreadDemo.$$[228]>

P0.218 srThreadDemo.$$[208]> sprawning thread

P0.218 srThreadDemo.$$[223]>    1

P0.218 srThreadDemo.$$[228]>

P0.218 srThreadDemo.$$[208]> sprawning thread

P0.218 srThreadDemo.$$[223]>    2

P0.218 srThreadDemo.$$[228]>

P0.218 srThreadDemo.$$[208]> sprawning thread

P0.218 srThreadDemo.$$[223]>    3

P0.218 srThreadDemo.$$[228]>

P0.218 srThreadDemo.$$[208]> sprawning thread

P0.218 srThreadDemo.$$[223]>    4

P0.218 srThreadDemo.$$[228]>

P0.218 srThreadDemo.$$[208]> sprawning thread

P0.218 srThreadDemo.$$[223]>    5

P0.218 srThreadDemo.$$[228]>

P0.218 srThreadDemo.$$[208]> sprawning thread

P0.218 srThreadDemo.$$[223]>    6

P0.218 srThreadDemo.$$[228]>

P0.218 srThreadDemo.$$[208]> sprawning thread

P0.218 srThreadDemo.$$[223]>    7

P0.218 srThreadDemo.$$[228]>

P0.218 srThreadDemo.$$[208]> sprawning thread

P0.218 srThreadDemo.$$[223]>    8

P0.218 srThreadDemo.$$[228]>

P0.218 srThreadDemo.$$[208]> sprawning thread

P0.218 srThreadDemo.$$[223]>    9

P0.218 srThreadDemo.$$[228]>

P0.218 srThreadDemo.go[538]> go go little threads. which thread will win? . . .

P1.219 srThreadDemo.thread. at Body[419]>    1

P1.219 srThreadDemo.thread. at Body[431]> threads done

P1.220 srThreadDemo.thread. at Body[419]>    2

P1.220 srThreadDemo.thread. at Body[431]> threads done

P1.221 srThreadDemo.thread. at Body[419]>    3

P1.221 srThreadDemo.thread. at Body[431]> threads done

P1.222 srThreadDemo.thread. at Body[419]>    4

P1.222 srThreadDemo.thread. at Body[431]> threads done

P1.223 srThreadDemo.thread. at Body[419]>    5

P1.223 srThreadDemo.thread. at Body[431]> threads done

P1.224 srThreadDemo.thread. at Body[419]>    6

P1.224 srThreadDemo.thread. at Body[431]> threads done

P1.225 srThreadDemo.thread. at Body[419]>    7

P1.225 srThreadDemo.thread. at Body[431]> threads done

P1.226 srThreadDemo.thread. at Body[419]>    8

P1.226 srThreadDemo.thread. at Body[431]> threads done

P1.227 srThreadDemo.thread. at Body[419]>    9

P1.227 srThreadDemo.thread. at Body[431]> threads done

P1.228 srThreadDemo.thread. at Body[419]>   10

P1.228 srThreadDemo.thread. at Body[431]> threads done

Why is AWAIT(threadsdone=10) never triggered?
--
Oberon at lists.inf.ethz.ch mailing list for ETH Oberon and related systems
https://lists.inf.ethz.ch/mailman/listinfo/oberon




More information about the Oberon mailing list