CompuServe Thread

#Generating PURE code?

11 messages in this thread
#31308From: Bob RakoskyJan 20, 1989 10:37 PM
PURE code is another term for 'reentrant'. The program cannot modify any portion of itself (code, data, or bss hunks). This is because the program may be executed by two or more tasks simultaneously, and a program that has modified itself in one task can really confuse the second task running the same code.
#31341From: Paul WhittemoreJan 21, 1989 12:48 AM
Pure is reentrant AND reexecutable, the latter meaning you assume nothing about the initial value of your global variables (i.e. no BSS) and use executable statements in your initialization code to give them their original values.
#31381From: Bob RakoskyJan 21, 1989 10:39 AM
While you are right, it is not necessary to stress both points. A program that is reentrant IS, by definition, reexecutable. In fact, using your definition's example of reexecutable, that program WOULD NOT be reentrant, since it is modifying itself (its global variables) at initialization, which is a definite NO-NO for rentrant code. The ONLY things that can be modified by a reentrant program are variables that exist on the stack, variables that exist solely in registers, or variables that have been AllocMem()'d.
#31450From: George BricknerJan 21, 1989 8:18 PM
Actually I'm surprized that any compiler for a multi-tasking system would generate anything but reentrant code. I haven't bought an Amiga C compiler yet, I'm just playing with PDC. Do both Lattice and Manx generate PURE code? I write OS/2 code for my employer. OS/2 shares the code segment of a program with all tasks and allocates separate segments for static and global data (the stack is in the global area too). (And we all know that the Amiga is better than any old Intel based system <grin>) Geo
#31477From: Bob RakoskyJan 21, 1989 11:13 PM
Actually, up until very recently, the Amiga compilers were incapable of generating reentrant code. The Amiga BCPL-based CLI environment was not designed to share code segments of loaded programs between tasks, so consequently, reentrancy was not a real issue for 'application' programs. It has always been an issue for things like run-time shared libraries and device drivers, and there were ways to generate these _MOSTLY_ in C, but a bit of assembler coding was required. One "limitation" that the 68000 has over the Intel processors is that the 68K is not forced to reference memory via a register-displacement type of addressing. This allows programs to contain direct memory references to data areas, which must be fixed once the program is loaded. Consequently, one in-memory copy of a program such as this cannot reference two areas of memory simultaneously (one for each concurrent task). This makes re-entrant use of global variables difficult. Of course, the 68K also allows references to memory via relative-register addressing, so there are ways around this problem – we just have to 'pretend' that we're working with a segmented architecture <grin>. Anyway, this is getting pretty rambling. Think I'll just end it here before I get totally confused 🙂
#31808From: Vic WagnerJan 23, 1989 11:30 PM
Bob, surely you jest. BCPL was _explicitly_ designed to share code and have separate data segments (called global vectors)
#31977From: Bob RakoskyJan 24, 1989 11:37 PM
Boy, some folks really get sensitive when a negative remark is made in the same sentence as BCPL! <grin> I should know better than to argue with you about the language! <ducking> Actually, what I was attempting to say (now that I know that I'm being watched 🙂 is that the manner in which the CLI environment was implented (such implementation having been written in BCPL but not necessarily because it was written in BCPL) was not really designed to support shared code segments for multiple processes. Better? My biggest complaint about the BCPL layers of the OS environment is that they are the poorest documented of all components of the Amiga software. There's a lot of deep, dark hidden voodoo there!
#32167From: Vic WagnerJan 26, 1989 4:09 AM
Actually, I think the system was written to handle shared code and separate data segments for multiple processes. I think the C compiler(s? were there more than one back then?) couldn't put the right stuff in to the loader text to support it. Thus, it just may have been that the C people didn't want to look at the BCPL requirements. That it was documented poorly is true. I believe one of the reasons was that MetaComCo wished to make some enhancements to AmigaDOS which would require some changes to the GLOBVEC. In those days documenting ANYTHING, no matter how severe the warnings were about it not being stable would just have gotten CBM hollered at if things changed. Do you remember the abortive attempt to 'fix' the cursor 'hot spot' which is off by one pixel? EA screamed so loud that CBM (in error, IMHO) backed down, and now we all live with a one pixel error in pointer hot spot.
#32241From: Bob RakoskyJan 26, 1989 7:35 PM
I sure do remember the off-by-one problem that CBM wanted to fix but had to back out. That's a tough one, though, where your d*mned if you do and d*mned if you don't. I don't think that, at that point in the development of the CBM software market, it would have been wise to "break" some of the existing major software packages, so I think that the right decision was made. Regarding the splitting of load modules into sharable code segments and separate (but equal) data segments, I really don't see anything in either the Process or CLI structures that look like they are there to support it. There also is no documented dos.library call to spawn off a new Process, using an existing, loaded, shared SegList. Consequently, I stand by my original contention that the capability was never designed in. As far as the existing C compiler(s) (counting the original Lattice compiler, if you must, and the Greenhills cross-dev system) – there just didn't exist (from what I can tell) any "standard" for them to aim at, other than the documented Object/Executable Hunk Format standards. And those definitions don't really support the shared code segments/separate data segment models. There was no defined method for anything but 32-bit reloc's, which implies hard, relocatable addresses.
#31610From: John DraperJan 22, 1989 8:37 PM
First, you must realize that reentrant code is not a prerequisite for multitasking, and secondly, that though reentrancy is desirable for certain classes of programs, it is by no means cheaply obtained. There is considerable overhead in making a program reentrant, both from a memory usage and from a speed point of view, especially in the initialization portion f a program. What is the minumum memory requirement for OS/2? 2 megs? How much is left for user programs at that size memory? 🙂
#31777From: George BricknerJan 23, 1989 8:14 PM
Larry, from my experience with OS-9, writing reentrant position independent code is fairly straight foward. Of course, OS-9 lets you define the size of your private data area in the module header and then dynamically allocates the storage for you. Writing reentrant code on an IBM mainframe is much harder and requires a lot of extra code due to they way they build parameter lists within the OS services macros. Writing reentrant code on the IBM Series/1 is real easy as they designed the OS services macro parameter lists. Writing reentrant code on OS/2 is easy too, but anything developed on those Intel CPUs are memory pigs. Speaking of memory pigs: OS/2 requires a minimum of 1.5 to 2 megs just to BOOT; The Presentation Manager requires about a meg; The Communications Manager requires about a meg; The Database and Query Managers require about a meg; The LAN Server requires over TWO megs. Oh, you want to run applications? IBM actually said to figure about a meg per application. They sure like round megabytes, don't they? I was amazed at how much function William Hawes put in Arexx in 32K. I'm waiting for IBM's OS/2 Rexx to see how many hundreds of K are required to equal Arexx.