Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!bloom-beacon!apple!oliveb!sun!pepper!cmcmanis From: cmcmanis%pepper@Sun.COM (Chuck McManis) Newsgroups: comp.sys.amiga.tech Subject: Re: CBM, Why did you make it so hard? Keywords: Graphics Libraries, reentrancy Message-ID: <94205@sun.Eng.Sun.COM> Date: 16 Mar 89 00:55:57 GMT References: <913@dover.uucp> Sender: news@sun.Eng.Sun.COM Reply-To: cmcmanis@sun.UUCP (Chuck McManis) Organization: Sun Microsystems, Mountain View Lines: 103 In article <913@dover.uucp> fullmer@dover.UUCP (Glen Fullmer) writes: >1. Why didn't the developers of the C compilers agree on a common linkable > format? Because they are different companies and have/had different priorities. Commodore/Amiga defined the "standard" object file format and documented it in the developers documents. Lattice, being the "official" C compiler for the Amiga used it. Aztec on the other hand already had an object module format that their code generators produced and it was simpler to retain that and only wack the linker to produce Amiga standard executables. This is a classic "Time to Market" trade-off. Anyway, that was the history. >2. How does one make a generic package, like his graphics package, both > reexecutable and reentrant? Does it require specific register allocation > via assembler programming? Or is there an easier way? A different > global hook that can be used to hang environments on? See the excellent Article by Carolyn Scheppner(sp?) in Amiga Mail on how to make your code re-entrant. If you don't get Amiga Mail, see if you can get back issues from CBM directly. (CATS, 1200 Wilson Dr, Westchester PA, 19380) Generally, reexecutable requires only that you don't use uninitialized variables or assume your globals are initialized to zeros, reentrant means that you don't store state in global variables, and you arbitrate access to those global variables that you have. >3. How does one restore the environment, for example, after an interrupt? What environment? If you context is on the stack (local variables) then you just return. If you change things that affect other processes using your code at interrupt time, then you have a bug. (Generally, during exception processing of any type one saves any values that your don't "own" like register contents, and then restore them before exit.) >4. Is making a package that must retain context both over the life of a > call and the life of the session different than "pure" residentable > code? If so, how are they different, and what are the coding > differences? Generally "life of a call" context is stored in local variables on the stack. "Life of a session" is handled in one of two ways, the first is to create a "session handle" when you first access the library. Do an OpenLibrary() followed by a NewSession() call. The library may copy a default context into the handle and then this handle is passed with all calls to the graphics library. In the case of the Amiga graphics library the "session handle" is the RastPort structure. The other method is to create a context in the task structure itself. This is much more difficult but certainly possible. Optional info : Generally, if you create a session handle that is simply a structure such as the RastPort in graphics.library, it has the advantage of speed because the handle is the data. Unfortunately, it also has the problem of compatibility later because changes to this structure will directly impact any program that "looks inside" of it. A common way around this problem is to return an index rather than the actual structure to the program. This makes the handle opaque and allows the graphics library to play around with the actual structure without breaking anyones code. >5. How did CBM do this for their libraries? Well see the RastPort discussion above. >6. Why isn't it simpler? Programming on real computers is always harder than programming on microcomputers. The flexibility and usefulness of a multitasking kernel puts certain restrictions on what you can do but opens up the capabilities of what you can accomplish. Anything can be simplified by making assumptions about what will and will not go on, but those same assumptions limit everything else as well. If you make the assumption that everyone using the graphics library will have a 2 bitplane, 640 X 200 pixel screen open, then all sorts of stuff becomes easier. You always know where to clip lines, or how many color registers you will be using etc. But that limits the other programmer who wants to use the same library with a 704 X 440 screen. >Granted, a lot of this is probably very naive for some of you guys, but >where does one learn it? References? Generally global concepts such as the differences between reentrant and reexecutable are taught in Universities. In terms of schools I am familiar with, 2 year programs will teach sort of a mechanical programming style. Using canned algorithims to solve specific problems. Whereas 4 year schools will tend to teach concepts and how to devise an algorithim. Good system design is something that comes from practice. [Writing this graphics library should be some good experience!] Whenever you write something, no matter how long you have been at it, you should go back and look at it a year later. At that time all of it's flaws and deficiencies will be glaringly apparent. Learn from that, take note of areas you didn't consider. Then add those questions to the repetoire of the ones you ask yourself when starting a new design. It's a never ending quest but after while the questions will be quite esoteric. [Example : What if I wanted to port this to a 12bit machine with only 4010 terminals for output, how would that affect the design?] The answers need not be completely relevent but they should point out weaknesses in the design. --Chuck McManis uucp: {anywhere}!sun!cmcmanis BIX: cmcmanis ARPAnet: cmcmanis@sun.com These opinions are my own and no one elses, but you knew that didn't you.