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