Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!csd4.milw.wisc.edu!leah!rpi!rpi.edu!deven From: deven@pawl.rpi.edu (Deven Corzine) Newsgroups: comp.sys.amiga.tech Subject: Re: ReallocMem Message-ID: Date: 3 Apr 89 02:30:29 GMT References: <6406@cbmvax.UUCP> <6464@cbmvax.UUCP> <432@antares.UUCP> Sender: usenet@rpi.edu Reply-To: shadow@pawl.rpi.edu (Deven T. Corzine) Organization: RPI Public Access Workstation Lab, Troy NY Lines: 147 In-reply-to: jms@antares.UUCP's message of 1 Apr 89 10:42:15 GMT In article <432@antares.UUCP> jms@antares.UUCP (Joe Smith) writes: >In article shadow@pawl.rpi.edu (Deven T. Corzine) writes: >>... Now, if C-A will add a ReallocMem to Exec V1.4+, it won't be a problem. >I don't understand how ReallocMem could ever work under AmigaDOS >unless the caller always does a Forbid before the FreeMem and a Permit >after the ReallocMem. As soon as you free memory on the Amiga, some >other task may get a chance to run and get the block you just freed. >(Memory blocks are either in use, or completely free - available to >anyone. There are no other possiblilities.) With Unix, each process >gets its own private virtual address space so that the other guy's >alloc won't interfere with your alloc. And sbrk provides contiguous >blocks of virtual memory, something which cannot be done with AmigaDOS. Forget AmigaDOS. This is Exec-level, and has nothing whatsoever to do with BCPL, the file system, or any other part of AmigaDOS itself. You are indeed missing the point. First, the purpose of having a ReallocMem() function is NOT to reallocate a previously freed block of memory; that is a peculiarity of some versions of Unix, which while handy, is irrelevant here. The purpose of having a ReallocMem() function is (would be) to modify the passed memory block -- either the size or type of the block. It is understood that after the ReallocMem, the old pointer is no longer valid, and the new pointer returned must be used - if the block can't be expanded or shrunken or otherwise modified where it is, it will be moved, unless the change can not be accomodated at all, in which case the old block remains allocated and intact, and the function call returns an error. You are correct in saying that sbrk() will extend a contiguous data segment, but the fact is that even though in Unix malloc() and realloc() will make calls to sbrk() which calls brk() to get more memory... You don't need to do that, because of the way memory management is done on the Amiga. You can have a malloc() routine which calls AllocMem() instead and have free() call FreeMem(), etc. I intend to to exactly that for "Amigix" and I expect to dummy- implement sbrk() and brk(), probably. After all, in Unix, sbrk() and brk() are almost NEVER called directly... only indirectly from malloc(), calloc(), etc. Those routines will call AllocMem instead, eliminating the need or value in writing sbrk() and brk(). >You keep saying that it is trivial to add ReallocMem to the OS. Given the >fact that all tasks on the Amiga share the same virtual=physical address >space (currently), I believe it is very difficult. I would venture to say >that it is impossible in version 1.x - you will have to wait for 2.0 or 3.0. And I stand by that statement. It remains a trivial task to write a proper ReallocMem for Exec. It would be about twice as complex as AllocMem, which I can't see being very complex, considering the simplicity of its task. Adding a ReallocMem to Exec has NOTHING to do with having virtual/mapped memory or not. True, a ReallocMem would need to start with a Forbid() and end with a Permit(), but so must AllocMem and FreeMem. It is only for the duration of the function call, which will be short. In article <11848@umn-cs.CS.UMN.EDU> brant@uf.msc.umn.edu (Gary Brant) writes: >In article <432@antares.UUCP> jms@antares.UUCP (Joe Smith) writes: [...] >You're missing the point; if you FreeMem first, you don't even need >ReAllocMem. ReAllocMem should take a pointer to a block and a new size >and return a block of the requested size. If a new block is needed, >ReAllocMem copies the contents of the old block to the new one before >releasing the old block to the free storage pool. I don't see why any >Forbid/Permit's would be needed here. In some versions of Unix, you can indeed free a block, and call realloc() with a pointer to the freed block, and the block will be reallocated intact. This only works if there were no malloc(), realloc() or free() calls between the free(ptr) and realloc(ptr). This is a rather strange (but useful) semantic of realloc, but not the primary reason for realloc. To implement ReallocMem properly, the function would have to Forbid(), check whether or not the reallocation request can succeed AFTER the old block is freed, (without actually freeing the block) return with an error (after a Permit()) if it can't, otherwise free the old block, allocate the new one and copy the block if it starts elsewhere, Permit() and finally return the pointer to the new block. It should always keep the block at the same address if at all possible, to avoid unnecessary copying. Clearly, such a routine would depend on the granularity of memory allocation, and as such, dependant on a particular version of Exec. Therefore, such a function ought to be included in exec.library for V1.4 and beyond, so that it will be consistent. IMHO. Alternatively, you could write a function which does a Forbid(), AllocMem() for the new block, return with an error (after a Permit()) if the AllocMem() fails, otherwise copy the old block to the new, FreeMem() the old block, Permit() and return a pointer to the new block. The fault in using this method is that there must be enough free memory to hold BOTH blocks of memory at once, so it can easily fail if you are simply SHRINKING a memory block, if there is not enough free memory. Hence, it is far preferable to do the job right... which means adding ReallocMem to exec.library... In article <1394@hub.ucsb.edu> dougp@sbphy.ucsb.edu writes: >In article <11848@umn-cs.CS.UMN.EDU> brant@uf.msc.umn.edu (Gary Brant) writes: [...] >You might also include the ability to change the type of memory by >specifing a new set of memory type flags. Of course this would >REQUIRE copying the memory if you changed from FAST to CHIP, but it >might require only messing with some registers in the MMU of future >amigas if you changed from PUBLIC to private ram. Absolutely. The function arguments that make most sense for ReallocMem are: APTR ReallocMem(oldblock, oldsize, newsize, attributes, attributemask) APTR oldblock; /* pointer to old block */ ULONG oldsize; /* size of old block */ ULONG newsize; /* size of new block */ ULONG attributes; /* attributes of new block */ ULONG attributemask; /* mask of attribute bits to be changed */ The ReallocMem function should also ideally handle NULL special cases gracefully; that is: ReallocMem(0,0,BUFSIZE,MEMF_CLEAR,-1); should act as a: AllocMem(BUFSIZE,MEMF_CLEAR); and: ReallocMem(oldblock,oldblocksize,0,0,0); should act as a: FreeMem(oldblock,oldblocksize); [See comp.std.c if you want justification for this.] *sigh* Yet another long article... Well, at least it's only 1 reply to 3 articles... 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.