Index: AutoFlushWr.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/libm3/src/rw/AutoFlushWr.m3,v retrieving revision 1.1.1.1.6.1 diff -u -r1.1.1.1.6.1 AutoFlushWr.m3 --- AutoFlushWr.m3 31 Aug 2009 07:31:22 -0000 1.1.1.1.6.1 +++ AutoFlushWr.m3 7 Dec 2009 12:55:34 -0000 @@ -16,6 +16,7 @@ IMPORT Wr, WrClass, Time, Thread, Process; FROM Wr IMPORT Failure; FROM Thread IMPORT Alerted; +FROM UnsafeWr IMPORT FastClose, FastFlush, FastLength; (* A writer wr is *inactive* if wr.cur=wr.hi=wr.lo, and *active* otherwise. Notice that if wr is inactive, c(wr) = target(wr) (by WrClass.V2) @@ -64,6 +65,21 @@ init := Init; END; +PROCEDURE Copy(from, to: Wr.T) = +(* Copy the public fields from "from" to "to". + We don't necessarily need to copy all of them, but we do anyway. + Caller handles locking. *) +BEGIN + to.buff := from.buff; + to.st := from.st; + to.cur := from.cur; + to.lo := from.lo; + to.hi := from.hi; + to.closed := from.closed; + to.seekable := from.seekable; + to.buffered := from.buffered; +END Copy; + (* For wr of type T, wr.child is the writer to which wr's writing is forwarded. wr.delay is the inverse of the frequency with which wr will be flushed. If wr is active, wr.alarm is the next time @@ -78,13 +94,7 @@ WrClass.Lock(wr); WrClass.Lock(ch); TRY - wr.buff := ch.buff; - wr.st := ch.st; - wr.cur := ch.cur; - wr.lo := ch.lo; - wr.hi := ch.hi; - wr.closed := ch.closed; - wr.seekable := ch.seekable; + Copy(ch, wr); wr.buffered := TRUE; wr.child := ch; wr.onQ := FALSE; @@ -102,16 +112,14 @@ BEGIN WrClass.Lock(wr.child); TRY - wr.child.cur := wr.cur; + Copy(wr, wr.child); + (* We don't call FastSeek here because it fails if wr.child is not seekable, even if n = wr.cur. *) wr.child.seek(n); + Copy(wr.child, wr); FINALLY WrClass.Unlock(wr.child); END; - wr.buff := wr.child.buff; - wr.st := wr.child.st; - wr.cur := wr.child.cur; - wr.lo := wr.child.lo; - wr.hi := wr.child.hi; + LOCK mu DO IF NOT wr.onQ THEN wr.onQ := TRUE; @@ -137,44 +145,35 @@ BEGIN WrClass.Lock(wr.child); TRY - wr.child.cur := wr.cur; - wr.child.flush(); - - wr.buff := wr.child.buff; - (* Set everything empty. *) - wr.st := wr.child.st + wr.child.cur - wr.child.lo; - wr.cur := wr.child.cur; - wr.lo := wr.child.cur; - wr.hi := wr.child.cur; + Copy(wr, wr.child); + FastFlush(wr.child); + Copy(wr.child, wr); FINALLY WrClass.Unlock(wr.child); END; END Flush; PROCEDURE Length (wr: T): CARDINAL RAISES {Failure, Alerted} = + VAR res: CARDINAL; BEGIN WrClass.Lock(wr.child); TRY - wr.child.cur := wr.cur; - WITH res = wr.child.length() DO - wr.buff := wr.child.buff; - wr.st := wr.child.st; - wr.cur := wr.child.cur; - wr.lo := wr.child.lo; - wr.hi := wr.child.hi; - RETURN res; - END; + Copy(wr, wr.child); + res := FastLength(wr.child); + Copy(wr.child, wr); FINALLY WrClass.Unlock(wr.child); END; + RETURN res; END Length; PROCEDURE Close(wr: T) RAISES {Failure, Alerted} = BEGIN WrClass.Lock(wr.child); TRY - wr.child.cur := wr.cur; - wr.child.close(); + Copy(wr, wr.child); + FastClose(wr.child); + Copy(wr.child, wr); FINALLY WrClass.Unlock(wr.child); END; Index: FileWr.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/libm3/src/rw/FileWr.m3,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 FileWr.m3 --- FileWr.m3 24 Jan 2001 16:48:02 -0000 1.1.1.1 +++ FileWr.m3 7 Dec 2009 12:55:34 -0000 @@ -12,6 +12,7 @@ UNSAFE MODULE FileWr; IMPORT File, FS, Pathname, OSError, RegularFile, Wr, WrClass; +IMPORT RTIO, Fmt; PROCEDURE Open(p: Pathname.T): T RAISES {OSError.E} = BEGIN @@ -78,7 +79,11 @@ PROCEDURE Seek(wr: T; n: CARDINAL) RAISES {Wr.Failure} = BEGIN - IF NOT wr.seekable AND n # wr.hi THEN RAISE Error END; + IF NOT wr.seekable AND n # wr.hi THEN + RTIO.PutText("FileWr.Seek:wr.seekable=" & Fmt.Bool(wr.seekable) & ";n=" & Fmt.Int(n) & ";wr.hi=" & Fmt.Int(wr.hi) & "\n"); + RTIO.Flush(); + RAISE Error + END; TRY EmptyBuffer (wr); (* Maintains V4 -- we hope that on a seek failure the file Index: Rd.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/libm3/src/rw/Rd.m3,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 Rd.m3 --- Rd.m3 24 Jan 2001 16:48:02 -0000 1.1.1.1 +++ Rd.m3 7 Dec 2009 12:55:34 -0000 @@ -29,13 +29,9 @@ <*INLINE*> PROCEDURE GetChar (rd: T): CHAR RAISES {EndOfFile, Failure, Alerted} = - VAR res: CHAR; BEGIN LOCK rd DO - IF rd.cur = rd.hi THEN DoSeek(rd) END; - res := rd.buff[rd.st + (rd.cur - rd.lo)]; - INC(rd.cur); - RETURN res + RETURN FastGetChar(rd); END END GetChar; @@ -63,12 +59,9 @@ <*INLINE*> PROCEDURE GetWideChar (rd: T): WIDECHAR RAISES {EndOfFile, Failure, Alerted} = - VAR ch: WIDECHAR; BEGIN LOCK rd DO - IF rd.closed THEN Die() END; - IF NOT GetWC (rd, ch) THEN RAISE EndOfFile; END; - RETURN ch; + RETURN FastGetWideChar(rd); END END GetWideChar; @@ -116,8 +109,7 @@ RAISES {Failure, Alerted} = BEGIN LOCK rd DO - IF rd.closed THEN Die() END; - RETURN rd.getSub(str) + RETURN FastGetSub(rd, str); END END GetSub; @@ -177,12 +169,7 @@ (* rd is unlocked *) BEGIN LOCK rd DO - IF rd.cur # rd.hi THEN - RETURN FALSE - ELSE - IF rd.closed THEN Die() END; - RETURN rd.seek(rd.cur, FALSE) = SeekResult.Eof - END + RETURN FastEOF(rd); END END EOF; Index: UnsafeWr.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/libm3/src/rw/UnsafeWr.i3,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 UnsafeWr.i3 --- UnsafeWr.i3 24 Jan 2001 16:48:02 -0000 1.1.1.1 +++ UnsafeWr.i3 7 Dec 2009 12:55:34 -0000 @@ -105,5 +105,15 @@ (* Like Wr.PutText(wr, Fmt.LongReal(wr, precision, style)). *) PROCEDURE FastClose (wr: Wr.T) RAISES {Failure, Alerted}; +(* Like Wr.Close *) + +PROCEDURE FastSeek(wr: Wr.T; n: CARDINAL) RAISES {Failure, Alerted}; +(* Like Wr.Seek *) + +PROCEDURE FastFlush(wr: Wr.T) RAISES {Failure, Alerted}; +(* Like Wr.Flush *) + +PROCEDURE FastLength(wr: Wr.T): CARDINAL RAISES {Failure, Alerted}; +(* Like Wr.Length *) END UnsafeWr. Index: Wr.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/libm3/src/rw/Wr.m3,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 Wr.m3 --- Wr.m3 24 Jan 2001 16:48:02 -0000 1.1.1.1 +++ Wr.m3 7 Dec 2009 12:55:34 -0000 @@ -14,9 +14,6 @@ REVEAL Private = Thread.Mutex BRANDED OBJECT END; -(* FastPutChar and PutChar are identical except that PutChar acquires - and releases the lock while FastPutChar assumes it is already held. *) - (* It is invariant that for a closed writer "wr", "wr.buff = NIL" and "wr.lo = wr.hi". Therefore the check that "wr" is ready need not inspect "wr.closed" on the fast path. *) @@ -31,14 +28,14 @@ Thread.Release(wr) END Unlock; +(* FastPutChar and PutChar are identical except that PutChar acquires + and releases the lock while FastPutChar assumes it is already held. *) + <*INLINE*> PROCEDURE PutChar (wr: T; ch: CHAR) RAISES {Failure, Alerted} = BEGIN LOCK wr DO - IF wr.cur = wr.hi THEN DoSeek(wr) END; - wr.buff[wr.st + wr.cur - wr.lo] := ch; - INC(wr.cur); - IF NOT wr.buffered THEN wr.flush(); END; + FastPutChar(wr, ch); END; END PutChar; @@ -55,8 +52,7 @@ PROCEDURE PutWideChar (wr: T; ch: WIDECHAR) RAISES {Failure, Alerted} = BEGIN LOCK wr DO - PutWC (wr, ch); - IF NOT wr.buffered THEN wr.flush(); END; + FastPutWideChar(wr, ch); END; END PutWideChar; @@ -138,9 +134,7 @@ RAISES {Failure, Alerted} = BEGIN LOCK wr DO - IF wr.closed THEN Die() END; - wr.putString(a); - IF NOT wr.buffered THEN wr.flush(); END; + FastPutString(wr, a); END; END PutString; @@ -231,19 +225,29 @@ END FastPutLongReal; +PROCEDURE FastSeek(wr: T; n: CARDINAL) RAISES {Failure, Alerted} = + BEGIN + IF wr.closed OR NOT wr.seekable THEN Die() END; + wr.seek(n); + END FastSeek; + PROCEDURE Seek(wr: T; n: CARDINAL) RAISES {Failure, Alerted} = BEGIN LOCK wr DO - IF wr.closed OR NOT wr.seekable THEN Die() END; - wr.seek(n); + FastSeek(wr, n); END END Seek; +PROCEDURE FastFlush (wr: T) RAISES {Failure, Alerted} = + BEGIN + IF wr.closed THEN Die() END; + wr.flush(); + END FastFlush; + PROCEDURE Flush (wr: T) RAISES {Failure, Alerted} = BEGIN LOCK wr DO - IF wr.closed THEN Die() END; - wr.flush(); + FastFlush(wr); END; END Flush; @@ -255,11 +259,16 @@ END END Index; +PROCEDURE FastLength (wr: T): CARDINAL RAISES {Failure, Alerted} = + BEGIN + IF wr.closed THEN Die() END; + RETURN wr.length (); + END FastLength; + PROCEDURE Length (wr: T): CARDINAL RAISES {Failure, Alerted} = BEGIN LOCK wr DO - IF wr.closed THEN Die() END; - RETURN wr.length (); + RETURN FastLength(wr); END END Length; @@ -331,4 +340,3 @@ BEGIN END Wr. -