afc@mace.cc.purdue.edu (Greg Flint) (02/09/90)
I've been trying to use the "farmalloc" routine with Turbo C 2.0. I am trying to allocate numerous small units (e.g., 6 - 20 bytes with each call). I don't know the number or size of the units in advance -- it is data dependent -- so I can't use "farcalloc". The problem that I'm having is that when I request 1-8 bytes, I'm given 16. When I request 9-16, I'm given 32 bytes...and so on. This causes me to run out of memory long before I should. (This is determined by calling "farcoreleft" after each "farmalloc" call.) The manual says that I should get "n" bytes when I request "n" bytes, but I seem to be getting memory in paragraphs -- and 2x what I think I'd need even if it had to give them to me in 16 byte units. I called Bourland support -- what a waste of $'s that was -- and was told that "probably" memory was given out in paragraphs and that "probably" it was supposed to work that way -- regardless of what the manual says. In short, I got no info from Bourland. Does anyone have a patch or a code around for this problem? I know that I could do one big "farmalloc" and write my own "little malloc", but speed is important and I'd prefer not have to execute "C" code if assembler code (or a patch) is available. Besides, writing "little malloc" seems a lot like re-inventing the wheel. ------------------------------------------------------------------------------- Greg Flint Math G-169 (317) 494-1787 UUCP: purdue!klaatu.cc!afc Purdue Univ. Purdue University INTERNET: afc@klaatu.cc.purdue.edu Computing Ctr. West Lafayette, IN 47907 BITNET: flint@purccvm.bitnet
Ralf.Brown@B.GP.CS.CMU.EDU (02/09/90)
In article <4100@mace.cc.purdue.edu>, afc@mace.cc.purdue.edu (Greg Flint) wrote: }I've been trying to use the "farmalloc" routine with Turbo C 2.0. I am }trying to allocate numerous small units (e.g., 6 - 20 bytes with each }call). I don't know the number or size of the units in advance -- it is }data dependent -- so I can't use "farcalloc". } }The problem that I'm having is that when I request 1-8 bytes, I'm given }16. When I request 9-16, I'm given 32 bytes...and so on. This causes }me to run out of memory long before I should. (This is determined by }calling "farcoreleft" after each "farmalloc" call.) Depending on how farmalloc() is implemented, it may be calling DOS's memory allocation functions for each request. DOS allocates in multiples of one paragraph, with an additional paragraph of overhead for memory management. In addition, Turbo C will be taking 8 bytes off the top for its own memory allocation housekeeping info. As it turns out, TC 2.0 allocates in multiples of paragraphs anyway, unlike TC 1.x which allocated in multiples of two bytes (in both cases four to eight bytes of housekeeping info (depending on the memory model) are added before rounding up to the next multiple). }Does anyone have a patch or a code around for this problem? I know that I }could do one big "farmalloc" and write my own "little malloc", but speed }is important and I'd prefer not have to execute "C" code if assembler code }(or a patch) is available. Besides, writing "little malloc" seems a lot }like re-inventing the wheel. Depending on how it is done, it could be considerably faster than calling DOS for each request. Particularly if the allocation is permanent, i.e. you never intend to call free() on the block. Here is some code which I use for small permanent allocations, which virtually eliminates memory management overhead (16-32 bytes overhead for 8192 bytes of allocation, assuming 16-byte or smaller allocations). You may want to use farmalloc() instead of malloc() to allocate the blocks which get parceled out. #define PALLOC_SIZE 8192 /* increment in which palloc() gets memory */ typedef struct _palloc_rec { struct _palloc_rec *next ; int max_size ; int used ; char memblock[1] ; } PALLOC_REC ; static PALLOC_REC *palloc_chain = NULL ; #ifdef PROTOTYPES void *palloc(int n) ; #endif PROTOTYPES /************************************************************************/ /* palloc */ /* "permanent" version of malloc(). Items allocated with palloc() */ /* are not freed until the program terminates, providing a */ /* reduction in memory requirements because no allocation */ /* information needs to be kept */ /************************************************************************/ void *palloc(n) int n ; { PALLOC_REC *p = palloc_chain ; void *mem ; if (n > PALLOC_SIZE) return malloc(n) ; /* can't possibly fit into our blocks, so get a new mem block */ /* find a block with enough memory */ while (p && p->used + n >= p->max_size) p = p->next ; /* skip blocks with insufficient space */ if (p == NULL) /* block with enough space left? */ { /* no, allocate a new block */ if ((p = malloc(sizeof(PALLOC_REC) + PALLOC_SIZE)) == NULL) return NULL ; p->next = palloc_chain ; palloc_chain = p ; p->max_size = PALLOC_SIZE ; p->used = 0 ; } mem = (void *) (p->memblock + p->used) ; p->used += n ; return mem ; } -- UUCP: {ucbvax,harvard}!cs.cmu.edu!ralf -=- 412-268-3053 (school) -=- FAX: ask ARPA: ralf@cs.cmu.edu BIT: ralf%cs.cmu.edu@CMUCCVMA FIDO: Ralf Brown 1:129/46 "How to Prove It" by Dana Angluin Disclaimer? I claimed something? 14. proof by importance: A large body of useful consequences all follow from the proposition in question.
jwbirdsa@phoenix.Princeton.EDU (James Webster Birdsall) (02/10/90)
In article <4100@mace.cc.purdue.edu> afc@mace.cc.purdue.edu (Greg Flint) writes: >The problem that I'm having is that when I request 1-8 bytes, I'm given >16. When I request 9-16, I'm given 32 bytes...and so on. This causes >me to run out of memory long before I should. (This is determined by >calling "farcoreleft" after each "farmalloc" call.) >------------------------------------------------------------------------------- >Greg Flint Math G-169 (317) 494-1787 UUCP: purdue!klaatu.cc!afc > Purdue Univ. Purdue University INTERNET: afc@klaatu.cc.purdue.edu > Computing Ctr. West Lafayette, IN 47907 BITNET: flint@purccvm.bitnet Since I'm not at my computer just now, I can't say for sure, but I think that farmalloc is just an interface to the DOS memory-allocation functions. These, of course, allocate memory in paragraphs. Since several bytes at the beginning of every memory block are reserved for system use, when you try for 9 bytes, it has to give you two paragraphs, etc. Worse, there have been the occasional rumors about bugs in DOS's memory handling functions, leading to system corruption if lots of small blocks are allocated and released frequently. Things you could try: you could try switching to a larger memory model (one with multiple data segments) and use malloc(). I've never gotten malloc() to work right in larger memory models, but I've never tried very hard. Otherwise I think you're going to have to write or find a library of memory-management functions. -- James W. Birdsall jwbirdsa@phoenix.Princeton.EDU jwbirdsa@pucc.BITNET ...allegra!princeton!phoenix!jwbirdsa Compu$erve: 71261,1731 "For it is the doom of men that they forget." -- Merlin