Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!husc6!mit-eddie!ll-xn!ames!ucbcad!ucbvax!dewey.soe.berkeley.edu!oster From: oster@dewey.soe.berkeley.edu (David Phillip Oster) Newsgroups: comp.sys.mac Subject: Re: When to HLock Message-ID: <21204@ucbvax.BERKELEY.EDU> Date: Thu, 8-Oct-87 14:30:48 EDT Article-I.D.: ucbvax.21204 Posted: Thu Oct 8 14:30:48 1987 Date-Received: Sun, 11-Oct-87 09:16:51 EDT References: <960@mntgfx.MENTOR.COM> Sender: usenet@ucbvax.BERKELEY.EDU Reply-To: oster@dewey.soe.berkeley.edu.UUCP (David Phillip Oster) Organization: School of Education, UC-Berkeley Lines: 81 In article <960@mntgfx.MENTOR.COM> tomc@mntgfx.MENTOR.COM (Tom Carstensen) writes: >Question: Do you need to HLock in the following kind of situation?: >TEHandle TheText; >lines = (**TheText).nLines No. Here is a simple rule: Always lock handles if you pass a pointer to any part of the data of the handle to a procedure or system call. Unlock them as soon as possible so the memory manager can do a better job. Assume handles are unlocked. Remember, resources might be purgable, and the same conditions that cause handle data to move may also cause purgable resources to be flushed. Here is an example: PicHandle foo; foo = GetResource('PICT', 128); /* get the handle */ HLock(foo); /* passing address of part of foo's contents */ DrawPicture(foo, &(**foo).picFrame); HUnlock(foo); ... /* some later use of foo */ LoadResource(foo); /* foo is a resource. It might have been purged */ -------- versus PicHandle foo; Rect r; foo = GetResource('PICT', 128); /* get the handle */ r = (**foo).picFrame; /* copy the frame */ HNoPurge(foo); /* foo is a resource! */ DrawPicture(foo, &r); /* no lock needed */ HPurge(foo); ---------- The rule above ("any procedure call or op sys call") errs on the side of conservatism for a number of reasons: Suppose you are calling something that you _know_ does not rearrange the heap. You could be wrong for the following reasons: 1.) As the operating system changes, op. sys. that don't do heap scrambles today may tomorrow. 2.) As your program grows and changes, functions you call today may do heap scrambles tomorrow. 3.) The operating system call you may require assembly language glue, which might be in another CODE segment. The procedure you are calling today might get moved to another CODE segement as the program grows and changes. Loading code segments into memory causes heap scrambles. If you are conservative with your HLocks(), it will make your programs run less effiecently. Extraneous Lock/UnLocks in our programs cost us a whole 5 milliseconds every month! The alternative is La Bomba, or days spent debugging. I know which I'd rather choose. Pascal is particularly nasty. Pascal has these things called "Var parameters" that are like the C "pass the address with '&'" except there is no way for you to tell by reading a function call whether the compiler is going to pass the address of a variable or its value. I spoke with Bill Atkinson at the first Hacker's Conference and he said that unlocked handles across function calls was the _costliest_ source of bugs when he was debugging MacPaint. He said that the way he caught them was to use the DA "Monkey", which generates random key and mouse events. The first time he thought MacPaint was done, Monkey crashed it in under 5 minutes. The version shipped with the first macs had survived 2 weeks under the Monkey. (Consumer note: If you value your files, do not run Monkey on your hard disk.) --- David Phillip Oster --A Sun 3/60 makes a poor Macintosh II. Arpa: oster@dewey.soe.berkeley.edu --A Macintosh II makes a poor Sun 3/60. Uucp: {uwvax,decvax,ihnp4}!ucbvax!oster%dewey.soe.berkeley.edu