123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- (** Simple test module for low-level locks *)
- MODULE LLCounter;
- IMPORT SYSTEM, Machine, Objects, Trace;
- CONST
- Count = 4000000;
- TYPE
- Writer = OBJECT
- VAR
- c: LONGINT;
- BEGIN {ACTIVE}
- FOR c := 1 TO Count DO
- Increment
- END;
- Lock;
- Trace.String("Writer "); Trace.Address(SYSTEM.VAL(ADDRESS, SELF)); Trace.String(" finished. i = "); Trace.Int(i, 0);
- Trace.String(". c = "); Trace.Int(c, 0); Trace.Ln;
- Unlock
- END Writer;
- Reader = OBJECT
- BEGIN {ACTIVE}
- LOOP Read END
- END Reader;
- Printer = OBJECT
- VAR
- id, count: LONGINT;
- PROCEDURE & Init(i: LONGINT);
- BEGIN
- id := i
- END Init;
- PROCEDURE Print;
- BEGIN
- Lock;
- Trace.String("Printer: Inside a critical section. id = "); Trace.Int(id, 0); Trace.Ln;
- Unlock
- END Print;
- BEGIN {ACTIVE}
- (*FOR count := 0 TO 1000 DO*)
- LOOP
- Print
- END
- END Printer;
- IndependentWriter = OBJECT
- VAR
- i, c, id: LONGINT;
- lock: BOOLEAN;
- padding: ARRAY 30 OF CHAR;
- PROCEDURE & Init(id: LONGINT);
- BEGIN
- SELF.id := id
- END Init;
- BEGIN {ACTIVE}
- (*LOOP*)
- (*FOR c := 1 TO Count DO*)
- WHILE i < Count DO
- (*Lock;*)
- (*Machine.AcquireSpin(lock);*)
- INC(i);
- (*Machine.ReleaseSpin(lock)*)
- (*Unlock*)
- Test(ADDRESSOF(Bad), 0);
- Test(ADDRESSOF(Bad), 0)
- END;
- (*Lock;*)
- Trace.Int(id, 0); Trace.String(". i = "); Trace.Int(i, 0); Trace.Ln;
- (*Unlock*)
- END IndependentWriter;
- IndependentWriter2 = OBJECT
- VAR
- i, c, id, d: LONGINT;
- lock: BOOLEAN;
- padding: ARRAY 30 OF CHAR;
- PROCEDURE & Init(id: LONGINT);
- BEGIN
- SELF.id := id
- END Init;
- BEGIN {ACTIVE}
- FOR c := 1 TO Count DIV 10 DO
- FOR d := 1 TO 10 DO
- Lock;
- (*Machine.AcquireSpin(lock);*)
- INC(i);
- (*Machine.ReleaseSpin(lock)*)
- Unlock
- END;
- Objects.Yield
- END;
- (*Lock;*)
- Trace.Int(id, 0); Trace.String(". i = "); Trace.Int(i, 0); Trace.Ln;
- (*Unlock*)
- END IndependentWriter2;
- Buffer = ARRAY 1024 * 1024 OF CHAR;
- VAR
- i: LONGINT;
- lock: RECORD
- padding: ARRAY 31 OF CHAR;
- lock: BOOLEAN;
- END;
- w1, w2, w3, w4: Writer;
- r: Reader;
- p1, p2, p3, p4: Printer;
- iw1, iw2: IndependentWriter;
- iw21, iw22: IndependentWriter2;
- PROCEDURE Lock;
- BEGIN
- Machine.DisableInterrupts;
- (*Machine.AcquireSpin(lock.lock);*)
- (*Machine.Acquire(Machine.KernelLog)*)
- END Lock;
-
- PROCEDURE Unlock;
- BEGIN
- (*Machine.Release(Machine.KernelLog);*)
- (*Machine.ReleaseSpin(lock.lock);*)
- Machine.EnableInterrupts
- END Unlock;
- PROCEDURE Test(a, b: ADDRESS);
- BEGIN
- Test2(a, b)
- END Test;
- PROCEDURE Test2(a, b: ADDRESS);
- END Test2;
- PROCEDURE Bad;
- VAR
- bp, sp: ADDRESS;
- BEGIN
- Machine.DisableInterrupts;
- Trace.StringLn("BAD BOY");
- LOOP END
- END Bad;
- PROCEDURE Increment;
- VAR j: LONGINT;
- BEGIN
- Lock;
- INC(i);
- Unlock
- (*; FOR j := 0 TO 10000 DO END*)
- END Increment;
- PROCEDURE Read;
- BEGIN
- Lock;
- Trace.String("i: "); Trace.Int(i, 0); Trace.Ln;
- Unlock
- END Read;
- BEGIN
- Trace.StringLn("=== Begin Test ===");
- NEW(w1);
- NEW(w2);
- (*NEW(w3);
- NEW(w4);
- NEW(w1);
- NEW(w2);
- NEW(w3);
- NEW(w4);*)
- (*NEW(r);*)
- (*NEW(p1, 1);
- NEW(p2, 2);
- NEW(p3, 3);
- NEW(p4, 4);*)
- (*NEW(iw1, 1);
- NEW(iw2, 2)*)
- (*NEW(iw21, 1);
- NEW(iw22, 2)*)
- END LLCounter.
|