Module: common-dylan-test-suite Synopsis: Test conditional-update! Author: Tony Mann, Keith Dennison Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc. All rights reserved. License: Functional Objects Library Public License Version 1.0 Dual-license: GNU Lesser General Public License Warranty: Distributed WITHOUT WARRANTY OF ANY KIND // Testing conditional-update! define locked variable *locked-counter* = 0; define method debug-warn-on-fail () let count = *locked-counter*; format-l("Information: a conditional-update missed\n"); #f; end method; define method debug-locked-counter () let count = *locked-counter*; format-l("%d - new value from %s\n", count, current-thread().thread-name); count; end method; define method increment-value (x :: ) => (res :: ) thread-yield(); // make this more interesting x + 1; end method; define method decrement-value (x :: ) => (res :: ) thread-yield(); // make this more interesting x - 1; end method; define method cond-inc-count () while (conditional-update!(old = *locked-counter*) old.increment-value; success #f failure debug-warn-on-fail(); #t end conditional-update!) end while; debug-locked-counter(); end method; define method cond-dec-count () while (conditional-update!(old = *locked-counter*) old.decrement-value; success #f failure debug-warn-on-fail(); #t end conditional-update!) end while; debug-locked-counter(); end method; /* These versions spuriously compile incorrectly define method cond-inc-count () while (conditional-update!(old = *locked-counter*) thread-yield(); // make this more interesting old + 1; success #f failure debug-warn-on-fail(); #t end conditional-update!) end while; debug-locked-counter(); end method; define method cond-dec-count () while (conditional-update!(old = *locked-counter*) thread-yield(); // make this more interesting old - 1; success #f failure debug-warn-on-fail(); #t end conditional-update!) end while; debug-locked-counter(); end method; */ define test conditional-updates () let decrementers = 2; let incrementers = 2; let tries = 10; let vec = make(, size: (decrementers + incrementers)); *locked-counter* := 0; // first make a whole load of decrement threads for (i from 0 below decrementers) let name = concatenate("Cond-decrementer ", integer-to-string(i)); vec[i] := make(, name: name, function: method () for (j from 1 to tries) sleep(2.0); cond-dec-count(); end for; format-l("%s finished\n", name); end); end for; for (i from 0 below incrementers) let name = concatenate("Cond-incrementer ", integer-to-string(i)); vec[i + 2] := make(, name: name, function: method () for (j from 1 to tries) sleep(1.0); cond-inc-count(); end for; format-l("%s finished\n", name); end); end for; for (i from 0 below (decrementers + incrementers)) join-thread(vec[i]); end for; check-true("*locked-counter* is zero", *locked-counter* == 0); end test; define suite conditional-updates-suite () test conditional-updates; end suite;