MODULE BenchLocks;
IMPORT Machine, Kernel, Commands;
CONST
Level = Machine.KernelLog;
TYPE
Thread = OBJECT
VAR
nofLoops, holdTime : LONGINT;
i, j : LONGINT;
PROCEDURE &Init*(nofLoops, holdTime : LONGINT);
BEGIN
ASSERT((nofLoops > 0) & (holdTime >= 0));
SELF.nofLoops := nofLoops;
SELF.holdTime := holdTime;
END Init;
BEGIN {ACTIVE}
LOOP
FOR i := 7 TO 0 BY -1 DO
Machine.Acquire(i);
FOR j := 0 TO holdTime DO
(* skip *)
END;
Machine.Release(i);
END;
DEC(nofLoops);
IF (nofLoops <= 0) THEN EXIT; END;
END;
DecNofThreadsRunning;
END Thread;
VAR
nofThreadsRunning : LONGINT;
PROCEDURE DecNofThreadsRunning;
BEGIN {EXCLUSIVE}
DEC(nofThreadsRunning);
END DecNofThreadsRunning;
PROCEDURE Bench*(context : Commands.Context);
VAR start, i, nofThreads, nofLoops, holdTime : LONGINT; threads : POINTER TO ARRAY OF Thread;
BEGIN {EXCLUSIVE}
context.arg.SkipWhitespace; context.arg.Int(nofThreads, FALSE);
context.arg.SkipWhitespace; context.arg.Int(nofLoops, FALSE);
context.arg.SkipWhitespace; context.arg.Int(holdTime, FALSE);
IF (nofThreads > 0) & (nofLoops > 0) & (holdTime >= 0) THEN
context.out.String("Starting "); context.out.Int(nofThreads, 0);
context.out.String(" threads where each acquires each kernel lock ");
context.out.Int(nofLoops, 0); context.out.String(" times (HoldTime: ");
context.out.Int(holdTime, 0); context.out.String(") ..."); context.out.Update;
nofThreadsRunning := nofThreads;
NEW(threads, nofThreads);
start := Kernel.GetTicks();
FOR i := 0 TO LEN(threads)-1 DO
NEW(threads[i], nofLoops, holdTime);
END;
AWAIT(nofThreadsRunning = 0);
context.out.String("Time required: "); context.out.Int(Kernel.GetTicks() - start, 0);
context.out.String(" ms");
ELSE
context.out.String("Parameter error: nofThreads & nofLoops must be > 0, holdTime must be >= 0");
END;
context.out.Ln;
END Bench;
PROCEDURE TestAcquire*(context : Commands.Context);
VAR i, n, t: LONGINT;
BEGIN
IF context.arg.GetInteger(n, FALSE) & (n > 0) THEN
i := Kernel.GetTicks();
REPEAT t := Kernel.GetTicks() UNTIL t # i;
FOR i := 1 TO n DO
Machine.Acquire(Level);
Machine.Release(Level)
END;
t := Kernel.GetTicks() - t;
context.out.Int(n, 1); context.out.String(" loops, ");
context.out.Int(t*1000 DIV Kernel.second, 1); context.out.String(" ms");
context.out.Ln;
END;
END TestAcquire;
END BenchLocks.
SystemTools.Repeat 3
BenchLocks.Bench 32 100000 500 ~
BenchLocks.Bench 64 100000 500 ~
SystemTools.Free BenchLocks ~
Configuration.DoCommands
System.Time start
Aos.Call \w BenchLocks.TestAcquire 10000000 ~
System.Time lap
~
{P1 1000000 loops, 6105 ms} with Stats and nestCount
{P1 1000000 loops, 6005 ms} removed nestCount
{P1 1000000 loops, 2270 ms} disabled Stats
{P1 1000000 loops, 2201 ms} added quick acquire