Path: utzoo!attcan!uunet!lll-winken!csd4.milw.wisc.edu!leah!rpi!rpi.edu!shadow From: shadow@pawl.rpi.edu (Deven T. Corzine) Newsgroups: comp.sys.amiga.tech Subject: Re: Unix V7 functionality under (or along with) AmigaDOS? (*LONG*) Message-ID: Date: 19 Mar 89 13:22:54 GMT References: <0776.AA0776@julie> <6275@cbmvax.UUCP> <6299@cbmvax.UUCP> Sender: usenet@rpi.edu Reply-To: shadow@pawl.rpi.edu (Deven Thomas Corzine) Organization: RPI Public Access Workstation Lab, Troy NY Lines: 203 In-reply-to: jesup@cbmvax.UUCP's message of 15 Mar 89 23:36:59 GMT ARGH. Damned scheduled reboots. Lost my original reply to this message. *sigh* Gonna tentatively refer to the proposed system as "Amigix" for lack of a better unused name. If anyone can think of a better one, let me know. The sooner the better. :-) In article <6299@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes: >In article shadow@pawl.rpi.edu (Deven Thomas Corzine) writes: >>In article <6275@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes: >>>> What else? How about a standard tc_ExeceptionCode? >>>> Make SIGBREAKF_CTRL_C, and ^E exceptions. ^C will >>>>cause an "abort()" routine to be run. (signal() or sigvec()'able of >>>>course) The standard abort() should be able to run some number of >>>>clean up functions, and then it should call "exit()" Exactly what generates (and allocates?) the SIGBREAKF_CTRL_{C,D,E,F} signals? CON:? console.device? dos.library? What? And how can you change/disable/deallocate these signals? >>> Can't be done unless you can GUARANTEE the PC will not be in a ROM >>>routine, or with a Forbid() or LockIBase or ... held. Exceptions aren't as >>>useful as you think. >>I haven't looked into exceptions too closely, but they seem to be of >>some value, at least. How much, I'm not quite sure. > They are of some value, but not as much as unix signal handlers. >The idea originally was the same as Unix signal handlers, but it turns out >to not be as useful, since they can cause important resources to be lost, >and locking mechanisms to be defeated. Well, if at ALL possible, I want to implement Unix signal handlers, or as close as I can get. First, exactly HOW are exceptions and SigExcept() to be used? If a task is RemTask()'d while in a Forbidden state, does Exec perform an implicit Permit(), or does the system merely die? (Same question goes for Disable()/Enable()...) I take it the danger is using exceptions is that the task might be in the middle of a ROM routine modifying system structures, and the system may not be internally consistent when the exception takes effect? (e.g. in the middle of an AllocMem() and modifying system memory free lists...) If not, what? Proposal - use exceptions to implement Amigix signal handlers. When a system routine is called, call a sigdisable() function which sets a flag in the Amigix process structure. If an exception is called and the exception handler finds the flag set, it simply returns so as not to interrupt any system calls. After the system call, sigenable() would be called to enable the exception handler AND process any pending signals. As for resources allocated, the solution is resource tracking. Both the signal disabling and resource tracking are best done at the libcall level by patching all (ugh) of the library vectors... either just in exec.library, or globally in all libraries. (Not too nice to modify all the library jump vectors in the world, but I don't see any other really viable alternative. Of course, the sigdisable() and sigenable() calls would have no effect on AmigaDOS processes or simple Exec tasks; they would only affect Amigix processes. The tracker functions could be written to only operate on Amigix processes, or on all tasks. A medium option is for the tracker functions to note any allocated but not freed resources, but only act on them for Amigix processes, in the form of the Amigix process cleanup routines. (Such routines could then easily be made available for use by tasks and AmigaDOS processes, probably via an OpenLibrary("amigix.library",0) call...) Ideally, the tracker routines would be 2 general-purpose routines with arguments indicating what arguments from the call need to be preserved for later deallocation, along with the address of the jump vector for the deallocation routine, with information on how to format the arguments for the deallocation. However, as such routines would enormously complicate the calling sequence and probably slow things down unacceptably and use unnecessary memory, specific functions (one for AllocMem(), another for FreeMem(), etc.) A patch could even be added to OpenLibrary() to patch any new libraries installed into the system (such as disk-based libraries) if they haven't been. Gawd, but what a mess. *sigh* >>> One can get job control (at least the unix ^z part of it) >>>without exceptions. The shell simply notices ^f and stops waiting for >>>the current sub-process to complete. Does require running all >>>programs in other processes. This has been done by at least one >>>person. >>But that isn't really job control. It's more like ^Z followed by a >>bg. It doesn't stop the job, only waiting for it. How about having a >>function to suspend a task? It could freeze the exec task, optionally >>causing an exception so the process can clean up some... > True, it's not exactly the same semantics as ^Z, but it gives >you the most commonly used feature of it. There is no real support in >exec for non-executing tasks. A common use is indeed ^Z followed by bg, for when the user forgot the & sign, but real job control is need for you to actually switch between jobs and multiplex them on one (virtual) terminal. Unfortunately, it will most likely necessitate rewriting (in whole or in part) the console.device... Possibly making a tty.device which opens the console.device and adds functions, such as those needed to do the full job control correctly. (e.g. Unix "stty TOSTOP", etc.) >>>> It ISN'T fork()/exec(), but it does make a much more orthogonal >>>>system, shells send messages to "execute" servers, much the same >>>>way that comm programs send messages to "serial" devices... >>> In fact, exactly how I do it. >>Meaning? > Meaning in my shell (though maybe not in the ancient version >you have) I send messages to subprocesses that do all actual program >execution for me. The message includes seglist, priority, current >directory, input and output streams, etc, etc. When the program exits >it sends the message back with the return code. I can have any number >of these running for pipes, or background tasks (via ^f or &). Mmm. Not ideal, but a very workable system... >>As for implementation, I think the way to go is to number file >>descriptors sequentially starting at 0, as in Unix, with 0 for stdin, >>1 for stdout and 2 for stderr. However, the file descriptors would >>NOT be kept in a static array, but instead in an Exec list, which >>would be sorted from most-recently-used to least-recently-used -- when >... >>That should be the most efficient while keeping everything dynamic and >>flexible. Finding a free file descriptor for and open() or dup() call >>would be quite inefficient, however. Unless, perhaps, a list of file >>descriptor "holes" were kept... Only keeping track of unused >>descriptors up until the highest-numbered file descriptor (which would >>also be recorded) since all after that one are automatically free... > It sounds pretty good to me. Just make sure close merges in >the holes correctly (I assume the holes will stored as ranges). Sounds good to me, too. :-) Yes, the holes would be stored as ranges. And the final range may as well be left in for consistency. I'm considering numbering Amigix processes similarly. (for kill(), ps(1), etc.) Comments/suggestions? Next question... exactly how do I go about handling both task traps and Alert() calls (and "task held"'s?) such that I can recover from them (killing [and cleaning up] the offending process and dumping core if serious enough) without the usual GURU... (i.e. how can I cause only a Signal() call when the system would normally GURU?) How (for example) does GOMF (usually) trap it? (and why does it sometimes miss?) Next... How can I have the run-time library (opened by OpenLibrary() in the process startup long before the new process image begins to run) return a secondary value in the global variable errno? Is it possible with allowing #pragmas for the library, or MUST I use stub routines in a compile-time library? Is it possible to specify such an return sequence with #pragma in Lattice? I suppose I could have as part of the necessary startup routine code to store the address of errno in a field in the Amigix process structure. I may be stuck with that option, though it is somewhat of a kludge... Next... WHY is there no ReallocMem() in exec.library??? It should be fairly trivial to implement; a Forbid(), scan the memory list to see if there would be be an appropriately sized block AFTER the old block is released, and if so, release the old block, allocate the new one, byte copy the old block to the new one (it must handle overlapping blocks) and Permit() and return the new block. Simple. I could implement it in 30-45 minutes at most. So WHY isn't it in there??? Geez. I find it real hard to believe no one designing Exec had heard of Unix's realloc() call, for example. I find it even harder to believe that anyone might consider such a function to be useless. Don't you people realize how frustrating it is not to be able to SHRINK a window because there isn't enough memory to hold both the old and new window bitmaps at once??? *sigh* [flame off] Next... How can a terminating task safely and legally deallocate the memory section the terminiation code is executing it? Forbid(), FreeMem(), RemTask(0L)? (with implicit Permit() at RemTask()?) Some other way? What? Ah, well... this is enough for now... I'm sure I'll think of something new when I make my next post... (in a few minutes...) :-) Deven -- ------- shadow@pawl.rpi.edu ------- Deven Thomas Corzine --------------------- Cogito shadow@acm.rpi.edu 2346 15th Street Pi-Rho America ergo userfxb6@rpitsmts.bitnet Troy, NY 12180-2306 (518) 272-5847 sum... In the immortal words of Socrates: "I drank what?" ...I think.