dcrevier@jarthur.Claremont.EDU (Dan Crevier) (07/20/90)
I remember a long time ago a discussion about malloc, and bugs in it. Was there ever a new version of malloc posted or a good fix? Dan Crevier dcrevier@jarthur.claremont.edu
steve@thelake.mn.org (Steve Yelvington) (07/23/90)
[In article <7885@jarthur.Claremont.EDU>, dcrevier@jarthur.Claremont.EDU (Dan Crevier) writes ... ] > I remember a long time ago a discussion about malloc, and bugs in it. Was > there ever a new version of malloc posted or a good fix? The problem is in Malloc(), GEMDOS function 0x48. There is a limit on how many times you can call it, and I think you have to free memory in the reverse order. TOS 1.4 may have fixed some of these problems, but you can hardly depend on TOS 1.4 being installed in the average ST when Atari is still shipping computers without it. Most C compilers get around the difficulties by calling Malloc() to allocate a large chunk of memory, then parceling out little chunks as necessary. You can see how this works by examining the source code to the dLibs C library. (There is a bug in dLibs realloc() function. First person to *post* a fix gets a banana split at the Cup 'N' Cone in White Bear Lake. Transportation not included. Offer void where prohibited by cholesterol levels.) -- Steve Yelvington at the lake in Minnesota steve@thelake.mn.org
steve@thelake.mn.org (Steve Yelvington) (08/24/90)
I've seen comments to the effect that calling Malloc() from a desk accessory is a Bad Thing, and I wonder if that is always true. I want to write a desk accessory that will filter ASCII text into a format suitable for Pagestream. The Pagestream ASCII import function is brain-damaged -- it will not properly handle normal text with hard returns at the end of each line and paragraphs separated by a blank line (which is what you're reading right now). I want the DA to wake up from evnt_multi get a filename using fsel_exinput compute the file size open the file Malloc() enough memory for the whole file read all of it into the buffer strip line enders (except blank lines) write the modified file back to the disk close the file Mfree() the buffer return to evnt_multi There would not be a chance for an application to terminate while the allocated memory was being held. If the memory allocation follows the same rules as file handle ownership, there would not be a problem. True or false? -- Steve Yelvington up at the lake in Minnesota steve@thelake.mn.org plains!umn-cs!steve
kbad@atari.UUCP (Ken Badertscher) (08/29/90)
As long as you don't go back into an event wait, you can Malloc all day long (Mfreeing what you Malloc when you're done with it, of course). The only time DA's have Malloc headaches if they try to Malloc memory outside their startup sequence is if they give the parent application a chance to terminate out from under them. The problem arises when an application calls appl_exit(). The AES does not give DA's enough time to clean up after themselves before the parent application's resources are released. It is possible for a DA to not get an AC_CLOSE message until you're already back at the desktop. Note that this also causes problems with DA's that open virtual workstations, since the VDI Mallocs memory for workstation information. A sequence of events like the following could cause problems: Run an application. Open a DA that opens a workstation or Mallocs some memory. Quit the application without closing the DA. At this point, the application calls appl_exit(), which returns before giving all DA's a chance to clean up. The application then terminates, and GEMDOS frees all the memory that was allocated while the program was running. Eventually, the AES will get around to telling the DA, "Oh, by the way, shut yourself down now." If the DA then tries to access any of the memory it had Malloced, it would be messing with memory that had already been freed. If this memory had since been reallocated, the DA would be changing someone else's memory. If it happened that the memory had been reallocated to someone else _at the same starting address_, it would be disastrous for the DA to Mfree that block. The solution is simple. DA's must only Malloc memory in an atomic (from the AES's point of view) operation, as Steve outlined. If a DA has more dynamic memory needs, it can allocate a heap for itself at startup, BEFORE IT MAKES ANY AES CALLS. The DA can then use it's own memory management within this heap. -- ||| Ken Badertscher (ames!atari!kbad) ||| Atari R&D System Software Engine / | \ #include <disclaimer>
jhenders@van-bc.wimsey.bc.ca (John Henders) (08/29/90)
Thanks for the explanation Ken. Would using an auto program to serve DA memory requests work? Could the auto program somehow wake up once Gem was initialized so it could use the gem pipeline to get requests for memory from DA's and attach them to it's basepage. If this worked,it would seem we could have one auto program handle requests from many DA's. I know this is off- topic from Steve's question,but I'm curious. Actually,I'd guess this is how the non reset proof version of Shadow works. John Henders Vancouver,BC
7103_2622@uwovax.uwo.ca (Eric Smith) (08/29/90)
In article <1632@van-bc.wimsey.bc.ca>, jhenders@van-bc.wimsey.bc.ca (John Henders) writes: > Thanks for the explanation Ken. Would using an auto program to serve > DA memory requests work? Could the auto program somehow wake up once Gem was > initialized so it could use the gem pipeline to get requests for memory from > DA's and attach them to it's basepage. If this worked,it would seem we could > have one auto program handle requests from many DA's. I know this is off- > topic from Steve's question,but I'm curious. Actually,I'd guess this is how > the non reset proof version of Shadow works. > (I'm not Ken, but...) I would say not. There's no way to "wake up" a TSR under TOS; from TOS's point of view the program is dead and buried. If you want to go for non-portable code, the desk accessory certainly could dig through the TOS memory allocation list and "attach" any memory it allocates to some other program that won't terminate (the desktop being an obvious candidate). This strikes me as being quite ugly, and moreover I'm not sure that it would be guaranteed to work. Your suggestion of having a "server" handle memory requests from DA's would work quite well under a multi-tasking system such as RTX or MiNT, and should be easy to code under either of those two systems. -- Eric R. Smith email: Dept. of Mathematics ersmith@uwovax.uwo.ca University of Western Ontario ersmith@uwovax.bitnet London, Ont. Canada N6A 5B7 ph: (519) 661-3638
fischer-michael@cs.yale.edu (Michael Fischer) (08/30/90)
In article <6828.26dba802@uwovax.uwo.ca> 7103_2622@uwovax.uwo.ca (Eric Smith) writes: >In article <1632@van-bc.wimsey.bc.ca>, jhenders@van-bc.wimsey.bc.ca (John Henders) writes: >> Thanks for the explanation Ken. Would using an auto program to serve >> DA memory requests work? Could the auto program somehow wake up once Gem was >> initialized so it could use the gem pipeline to get requests for memory from >> DA's and attach them to it's basepage. If this worked,it would seem we could >> have one auto program handle requests from many DA's. I know this is off- >> topic from Steve's question,but I'm curious. Actually,I'd guess this is how >> the non reset proof version of Shadow works. >> >(I'm not Ken, but...) >I would say not. There's no way to "wake up" a TSR under TOS; from TOS's >point of view the program is dead and buried. If you want to go for >non-portable code, the desk accessory certainly could dig through the TOS >memory allocation list and "attach" any memory it allocates to some other >program that won't terminate (the desktop being an obvious candidate). >This strikes me as being quite ugly, and moreover I'm not sure that it would >be guaranteed to work. There is a trick that will work (at least in TOS 1.4) but is also not portable. Namely, change the current process pointer to point to the DA before doing the Malloc, and restore it to its original value immediately afterwards. This causes Gemdos to think that the DA is the owner of the newly-allocated block, not the currently-running application, which is what you want. The current process pointer is kept in a documented low-memory location. What isn't officially sanctioned is changing the pointer; it is supposed to be read-only. Thus, the behavior of TOS when you change it is not guaranteed to be the same in future versions of TOS. Another warning besides the non-portability issue: memory fragmentation can become a real problem if DA's go around Mallocing memory at random times. What Ken described is much safer. -- ================================================== | Michael Fischer <fischer-michael@cs.yale.edu> | ==================================================
uace0@uhnix2.uh.edu (Michael B. Vederman) (08/30/90)
In article <1632@van-bc.wimsey.bc.ca> jhenders@van-bc.wimsey.bc.ca (John Henders) writes: > > Thanks for the explanation Ken. Would using an auto program to serve >DA memory requests work? Could the auto program somehow wake up once Gem was >initialized so it could use the gem pipeline to get requests for memory from >DA's and attach them to it's basepage. If this worked,it would seem we could >have one auto program handle requests from many DA's. I know this is off- >topic from Steve's question,but I'm curious. hmm... Interesting idea, but I doubt you'd get any better results. You'd have to hook into the evnt_multi or evnt_mesag handler or even hook into the appl_write handler and fake a waiting event or entirely intercept the appl_write call... Too much trouble, but interesting concept. >Actually,I'd guess this is how >the non reset proof version of Shadow works. Not actually... For what you suggest above, tho, a similar handler to Shadow could be implemented for DAs. It would require your intercepting the Malloc() call from Gemdos. What Shadow does is change the p_run pointer to it's basepage before mallocing a buffer, then switches it back to the value before. p_run is the current process basepage pointer. It's location is documented for TOS 1.2 and greater. > > John Henders > Vancouver,BC - mike vederman (co-author of Shadow) -- ------------------------------------------------------------------------------ Double Click Me | Double Click Software | P.O. Box 741206 | Houston, Tx, 77274 ------------------------------------------------------------------------------ Voice: (713)977-6520 | DC DESKTOP | DC FORMATTER | DC UTILITIES | and others
7103_2622@uwovax.uwo.ca (Eric Smith) (08/31/90)
In article <25938@cs.yale.edu>, fischer-michael@cs.yale.edu (Michael Fischer) writes: [ In response to a question about how a DA can Malloc memory ] > > There is a trick that will work (at least in TOS 1.4) but is also not > portable. Namely, change the current process pointer to point to the > DA before doing the Malloc, and restore it to its original value > immediately afterwards. This causes Gemdos to think that the DA is > the owner of the newly-allocated block, not the currently-running > application, which is what you want. The current process pointer is > kept in a documented low-memory location. What isn't officially > sanctioned is changing the pointer; it is supposed to be read-only. > Thus, the behavior of TOS when you change it is not guaranteed to be > the same in future versions of TOS. Another warning besides the > non-portability issue: memory fragmentation can become a real problem > if DA's go around Mallocing memory at random times. What Ken > described is much safer. > I hadn't thought of that trick; it's not a bad idea. As you say, though, it may not work in future versions of TOS. It certainly doesn't work under MiNT (which sets the current process pointer, but otherwise ignores it). I don't know about RTX, but I'd suspect that it would have similar problems. -- Eric R. Smith email: Dept. of Mathematics ersmith@uwovax.uwo.ca University of Western Ontario ersmith@uwovax.bitnet London, Ont. Canada N6A 5B7 ph: (519) 661-3638
gt1448b@prism.gatech.EDU (David P. Forrai) (09/02/90)
In a previous post on this subject, it was mentioned that making a call to v_opnvwk() did a Malloc, thus problems can result from DA's which call it. In ACSKEL.C, a v_opnvwk() is called when the DA is opened, and a v_clsvwk() is called when a DA is closed. Therfore, this example of a desk accessory is not coded "correctly". What is the correct way to call v_opnvwk()? Should it be done before the event loop and v_clsvwk() never called?
kbad@atari.UUCP (Ken Badertscher) (09/03/90)
gt1448b@prism.gatech.EDU (David P. Forrai) asks: | What is the correct way to call v_opnvwk()? Should it be done before | the event loop and v_clsvwk() never called? The best way for desk accessories to handle opening virtual workstations is for them to use them in the same way they would use any other dynamically allocated resources. Open the workstation, do VDI calls, close the workstation. It isn't a good idea to suck up a virtual workstation slot which may never be used. You're right, if that's what ACSKEL does, the behaviour in ACSKEL is incorrect. The effects of dynamic DA Malloc() and v_opnvwk() calls only recently became apparent, when the GEMDOS internal memory management was improved for TT TOS. A side effect of the change he made was that the likelihood of a freed block getting reallocated soon after being freed became much greater. In previous TOS versions, it takes longer for freed blocks to be reallocated. Because of this, you are less likely to see problems arise when DA's don't get a chance to clean up after themselves. It is still and always will be A Bad Idea to mess with memory you don't own, and that's effectively what DA's do if they dynamically Malloc memory (either directly or indirectly). To end on a happy note--the problem of DA's not getting a chance to free up their resources before having them yanked out from under them is FIXED in the AES version 3.0. The AES now actually waits until all desk accessories are back in an event wait before allowing an appl_exit caller to terminate. The new Control Panel (XCONTROL) takes advantage of this fact, and dynamically allocates memory to load Control Panel Extensions if it sees that it's on a TT. This should also be a great boon to desk accessory text editors and the like. -- ||| Ken Badertscher (ames!atari!kbad) ||| Atari R&D System Software Engine / | \ #include <disclaimer>