00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #define _MEMORY_SOURCE_
00030
00031 #include <stdio.h>
00032 #define _STDIO_INCLUDED_
00033
00034 #include "setup.h"
00035
00036 #include "constant.h"
00037 #include "envrnmnt.h"
00038 #include "memalloc.h"
00039 #include "router.h"
00040 #include "utility.h"
00041
00042 #include <stdlib.h>
00043
00044 #if WIN_BTC
00045 #include <alloc.h>
00046 #endif
00047 #if WIN_MVC
00048 #include <malloc.h>
00049 #endif
00050
00051 #define STRICT_ALIGN_SIZE sizeof(double)
00052
00053 #define SpecialMalloc(sz) malloc((STD_SIZE) sz)
00054 #define SpecialFree(ptr) free(ptr)
00055
00056
00057
00058
00059
00060 #if BLOCK_MEMORY
00061 static int InitializeBlockMemory(void *,unsigned int);
00062 static int AllocateBlock(void *,struct blockInfo *,unsigned int);
00063 static void AllocateChunk(void *,struct blockInfo *,struct chunkInfo *,size_t);
00064 #endif
00065
00066
00067
00068
00069 globle void InitializeMemory(
00070 void *theEnv)
00071 {
00072 int i;
00073
00074 AllocateEnvironmentData(theEnv,MEMORY_DATA,sizeof(struct memoryData),NULL);
00075
00076 MemoryData(theEnv)->OutOfMemoryFunction = DefaultOutOfMemoryFunction;
00077
00078 MemoryData(theEnv)->MemoryTable = (struct memoryPtr **)
00079 malloc((STD_SIZE) (sizeof(struct memoryPtr *) * MEM_TABLE_SIZE));
00080
00081 if (MemoryData(theEnv)->MemoryTable == NULL)
00082 {
00083 PrintErrorID(theEnv,"MEMORY",1,TRUE);
00084 EnvPrintRouter(theEnv,WERROR,"Out of memory.\n");
00085 EnvExitRouter(theEnv,EXIT_FAILURE);
00086 }
00087
00088 for (i = 0; i < MEM_TABLE_SIZE; i++) MemoryData(theEnv)->MemoryTable[i] = NULL;
00089 }
00090
00091
00092
00093
00094 globle void *genalloc(
00095 void *theEnv,
00096 size_t size)
00097 {
00098 char *memPtr;
00099
00100 #if BLOCK_MEMORY
00101 memPtr = (char *) RequestChunk(theEnv,size);
00102 if (memPtr == NULL)
00103 {
00104 EnvReleaseMem(theEnv,(long) ((size * 5 > 4096) ? size * 5 : 4096),FALSE);
00105 memPtr = (char *) RequestChunk(theEnv,size);
00106 if (memPtr == NULL)
00107 {
00108 EnvReleaseMem(theEnv,-1L,TRUE);
00109 memPtr = (char *) RequestChunk(theEnv,size);
00110 while (memPtr == NULL)
00111 {
00112 if ((*MemoryData(theEnv)->OutOfMemoryFunction)(theEnv,(unsigned long) size))
00113 return(NULL);
00114 memPtr = (char *) RequestChunk(theEnv,size);
00115 }
00116 }
00117 }
00118 #else
00119 memPtr = (char *) malloc(size);
00120
00121 if (memPtr == NULL)
00122 {
00123 EnvReleaseMem(theEnv,(long) ((size * 5 > 4096) ? size * 5 : 4096),FALSE);
00124 memPtr = (char *) malloc(size);
00125 if (memPtr == NULL)
00126 {
00127 EnvReleaseMem(theEnv,-1L,TRUE);
00128 memPtr = (char *) malloc(size);
00129 while (memPtr == NULL)
00130 {
00131 if ((*MemoryData(theEnv)->OutOfMemoryFunction)(theEnv,size))
00132 return(NULL);
00133 memPtr = (char *) malloc(size);
00134 }
00135 }
00136 }
00137 #endif
00138
00139 MemoryData(theEnv)->MemoryAmount += (long) size;
00140 MemoryData(theEnv)->MemoryCalls++;
00141
00142 return((void *) memPtr);
00143 }
00144
00145
00146
00147
00148
00149 #if WIN_BTC
00150 #pragma argsused
00151 #endif
00152 globle int DefaultOutOfMemoryFunction(
00153 void *theEnv,
00154 size_t size)
00155 {
00156 #if MAC_MCW || WIN_MCW || MAC_XCD
00157 #pragma unused(size)
00158 #endif
00159
00160 PrintErrorID(theEnv,"MEMORY",1,TRUE);
00161 EnvPrintRouter(theEnv,WERROR,"Out of memory.\n");
00162 EnvExitRouter(theEnv,EXIT_FAILURE);
00163 return(TRUE);
00164 }
00165
00166
00167
00168
00169
00170 globle int (*EnvSetOutOfMemoryFunction(void *theEnv,int (*functionPtr)(void *,size_t)))(void *,size_t)
00171 {
00172 int (*tmpPtr)(void *,size_t);
00173
00174 tmpPtr = MemoryData(theEnv)->OutOfMemoryFunction;
00175 MemoryData(theEnv)->OutOfMemoryFunction = functionPtr;
00176 return(tmpPtr);
00177 }
00178
00179
00180
00181
00182 globle int genfree(
00183 void *theEnv,
00184 void *waste,
00185 size_t size)
00186 {
00187 #if BLOCK_MEMORY
00188 if (ReturnChunk(theEnv,waste,size) == FALSE)
00189 {
00190 PrintErrorID(theEnv,"MEMORY",2,TRUE);
00191 EnvPrintRouter(theEnv,WERROR,"Release error in genfree.\n");
00192 return(-1);
00193 }
00194 #else
00195 free(waste);
00196 #endif
00197
00198 MemoryData(theEnv)->MemoryAmount -= (long) size;
00199 MemoryData(theEnv)->MemoryCalls--;
00200
00201 return(0);
00202 }
00203
00204
00205
00206
00207 globle void *genrealloc(
00208 void *theEnv,
00209 void *oldaddr,
00210 size_t oldsz,
00211 size_t newsz)
00212 {
00213 char *newaddr;
00214 unsigned i;
00215 size_t limit;
00216
00217 newaddr = ((newsz != 0) ? (char *) gm2(theEnv,newsz) : NULL);
00218
00219 if (oldaddr != NULL)
00220 {
00221 limit = (oldsz < newsz) ? oldsz : newsz;
00222 for (i = 0 ; i < limit ; i++)
00223 { newaddr[i] = ((char *) oldaddr)[i]; }
00224 for ( ; i < newsz; i++)
00225 { newaddr[i] = '\0'; }
00226 rm(theEnv,(void *) oldaddr,oldsz);
00227 }
00228
00229 return((void *) newaddr);
00230 }
00231
00232
00233
00234
00235
00236 globle long int EnvMemUsed(
00237 void *theEnv)
00238 {
00239 return(MemoryData(theEnv)->MemoryAmount);
00240 }
00241
00242
00243
00244
00245
00246 globle long int EnvMemRequests(
00247 void *theEnv)
00248 {
00249 return(MemoryData(theEnv)->MemoryCalls);
00250 }
00251
00252
00253
00254
00255
00256 globle long int UpdateMemoryUsed(
00257 void *theEnv,
00258 long int value)
00259 {
00260 MemoryData(theEnv)->MemoryAmount += value;
00261 return(MemoryData(theEnv)->MemoryAmount);
00262 }
00263
00264
00265
00266
00267
00268 globle long int UpdateMemoryRequests(
00269 void *theEnv,
00270 long int value)
00271 {
00272 MemoryData(theEnv)->MemoryCalls += value;
00273 return(MemoryData(theEnv)->MemoryCalls);
00274 }
00275
00276
00277
00278
00279
00280 globle long int EnvReleaseMem(
00281 void *theEnv,
00282 long int maximum,
00283 int printMessage)
00284 {
00285 struct memoryPtr *tmpPtr, *memPtr;
00286 int i;
00287 long int returns = 0;
00288 long int amount = 0;
00289
00290 if (printMessage == TRUE)
00291 { EnvPrintRouter(theEnv,WDIALOG,"\n*** DEALLOCATING MEMORY ***\n"); }
00292
00293 for (i = (MEM_TABLE_SIZE - 1) ; i >= (int) sizeof(char *) ; i--)
00294 {
00295 YieldTime(theEnv);
00296 memPtr = MemoryData(theEnv)->MemoryTable[i];
00297 while (memPtr != NULL)
00298 {
00299 tmpPtr = memPtr->next;
00300 genfree(theEnv,(void *) memPtr,(unsigned) i);
00301 memPtr = tmpPtr;
00302 amount += i;
00303 returns++;
00304 if ((returns % 100) == 0)
00305 { YieldTime(theEnv); }
00306 }
00307 MemoryData(theEnv)->MemoryTable[i] = NULL;
00308 if ((amount > maximum) && (maximum > 0))
00309 {
00310 if (printMessage == TRUE)
00311 { EnvPrintRouter(theEnv,WDIALOG,"*** MEMORY DEALLOCATED ***\n"); }
00312 return(amount);
00313 }
00314 }
00315
00316 if (printMessage == TRUE)
00317 { EnvPrintRouter(theEnv,WDIALOG,"*** MEMORY DEALLOCATED ***\n"); }
00318
00319 return(amount);
00320 }
00321
00322
00323
00324
00325 globle void *gm1(
00326 void *theEnv,
00327 size_t size)
00328 {
00329 struct memoryPtr *memPtr;
00330 char *tmpPtr;
00331 size_t i;
00332
00333 if (size < (long) sizeof(char *)) size = sizeof(char *);
00334
00335 if (size >= MEM_TABLE_SIZE)
00336 {
00337 tmpPtr = (char *) genalloc(theEnv,(unsigned) size);
00338 for (i = 0 ; i < size ; i++)
00339 { tmpPtr[i] = '\0'; }
00340 return((void *) tmpPtr);
00341 }
00342
00343 memPtr = (struct memoryPtr *) MemoryData(theEnv)->MemoryTable[size];
00344 if (memPtr == NULL)
00345 {
00346 tmpPtr = (char *) genalloc(theEnv,(unsigned) size);
00347 for (i = 0 ; i < size ; i++)
00348 { tmpPtr[i] = '\0'; }
00349 return((void *) tmpPtr);
00350 }
00351
00352 MemoryData(theEnv)->MemoryTable[size] = memPtr->next;
00353
00354 tmpPtr = (char *) memPtr;
00355 for (i = 0 ; i < size ; i++)
00356 { tmpPtr[i] = '\0'; }
00357
00358 return ((void *) tmpPtr);
00359 }
00360
00361
00362
00363
00364 globle void *gm2(
00365 void *theEnv,
00366 size_t size)
00367 {
00368 struct memoryPtr *memPtr;
00369
00370 if (size < sizeof(char *)) size = sizeof(char *);
00371
00372 if (size >= MEM_TABLE_SIZE) return(genalloc(theEnv,(unsigned) size));
00373
00374 memPtr = (struct memoryPtr *) MemoryData(theEnv)->MemoryTable[size];
00375 if (memPtr == NULL)
00376 {
00377 return(genalloc(theEnv,(unsigned) size));
00378 }
00379
00380 MemoryData(theEnv)->MemoryTable[size] = memPtr->next;
00381
00382 return ((void *) memPtr);
00383 }
00384
00385
00386
00387
00388 globle void *gm3(
00389 void *theEnv,
00390 size_t size)
00391 {
00392 struct memoryPtr *memPtr;
00393
00394 if (size < (long) sizeof(char *)) size = sizeof(char *);
00395
00396 if (size >= MEM_TABLE_SIZE) return(genalloc(theEnv,size));
00397
00398 memPtr = (struct memoryPtr *) MemoryData(theEnv)->MemoryTable[(int) size];
00399 if (memPtr == NULL)
00400 { return(genalloc(theEnv,size)); }
00401
00402 MemoryData(theEnv)->MemoryTable[(int) size] = memPtr->next;
00403
00404 return ((void *) memPtr);
00405 }
00406
00407
00408
00409
00410
00411 globle int rm(
00412 void *theEnv,
00413 void *str,
00414 size_t size)
00415 {
00416 struct memoryPtr *memPtr;
00417
00418 if (size == 0)
00419 {
00420 SystemError(theEnv,"MEMORY",1);
00421 EnvExitRouter(theEnv,EXIT_FAILURE);
00422 }
00423
00424 if (size < sizeof(char *)) size = sizeof(char *);
00425
00426 if (size >= MEM_TABLE_SIZE) return(genfree(theEnv,(void *) str,(unsigned) size));
00427
00428 memPtr = (struct memoryPtr *) str;
00429 memPtr->next = MemoryData(theEnv)->MemoryTable[size];
00430 MemoryData(theEnv)->MemoryTable[size] = memPtr;
00431 return(1);
00432 }
00433
00434
00435
00436
00437
00438
00439 globle int rm3(
00440 void *theEnv,
00441 void *str,
00442 size_t size)
00443 {
00444 struct memoryPtr *memPtr;
00445
00446 if (size == 0)
00447 {
00448 SystemError(theEnv,"MEMORY",1);
00449 EnvExitRouter(theEnv,EXIT_FAILURE);
00450 }
00451
00452 if (size < (long) sizeof(char *)) size = sizeof(char *);
00453
00454 if (size >= MEM_TABLE_SIZE) return(genfree(theEnv,(void *) str,(unsigned long) size));
00455
00456 memPtr = (struct memoryPtr *) str;
00457 memPtr->next = MemoryData(theEnv)->MemoryTable[(int) size];
00458 MemoryData(theEnv)->MemoryTable[(int) size] = memPtr;
00459 return(1);
00460 }
00461
00462
00463
00464
00465 globle unsigned long PoolSize(
00466 void *theEnv)
00467 {
00468 register int i;
00469 struct memoryPtr *memPtr;
00470 unsigned long cnt = 0;
00471
00472 for (i = sizeof(char *) ; i < MEM_TABLE_SIZE ; i++)
00473 {
00474 memPtr = MemoryData(theEnv)->MemoryTable[i];
00475 while (memPtr != NULL)
00476 {
00477 cnt += (unsigned long) i;
00478 memPtr = memPtr->next;
00479 }
00480 }
00481 return(cnt);
00482 }
00483
00484
00485
00486
00487
00488
00489 globle unsigned long ActualPoolSize(
00490 void *theEnv)
00491 {
00492 #if WIN_BTC
00493 register int i;
00494 struct memoryPtr *memPtr;
00495 unsigned long cnt = 0;
00496
00497 for (i = sizeof(char *) ; i < MEM_TABLE_SIZE ; i++)
00498 {
00499 memPtr = MemoryData(theEnv)->MemoryTable[i];
00500 while (memPtr != NULL)
00501 {
00502
00503
00504
00505
00506
00507
00508 cnt += (((unsigned long) i) + 19L) & 0xfffffff0L;
00509 memPtr = memPtr->next;
00510 }
00511 }
00512 return(cnt);
00513 #else
00514 return(PoolSize(theEnv));
00515 #endif
00516 }
00517
00518
00519
00520
00521
00522 globle intBool EnvSetConserveMemory(
00523 void *theEnv,
00524 intBool value)
00525 {
00526 int ov;
00527
00528 ov = MemoryData(theEnv)->ConserveMemory;
00529 MemoryData(theEnv)->ConserveMemory = value;
00530 return(ov);
00531 }
00532
00533
00534
00535
00536
00537 globle intBool EnvGetConserveMemory(
00538 void *theEnv)
00539 {
00540 return(MemoryData(theEnv)->ConserveMemory);
00541 }
00542
00543
00544
00545
00546 globle void genmemcpy(
00547 char *dst,
00548 char *src,
00549 unsigned long size)
00550 {
00551 unsigned long i;
00552
00553 for (i = 0L ; i < size ; i++)
00554 dst[i] = src[i];
00555 }
00556
00557
00558
00559
00560
00561 #if BLOCK_MEMORY
00562
00563
00564
00565
00566
00567 static int InitializeBlockMemory(
00568 void *theEnv,
00569 unsigned int requestSize)
00570 {
00571 struct chunkInfo *chunkPtr;
00572 unsigned int initialBlockSize, usableBlockSize;
00573
00574
00575
00576
00577
00578
00579 if (sizeof(char) != 1)
00580 {
00581 fprintf(stdout, "Size of character data is not 1\n");
00582 fprintf(stdout, "Memory allocation functions may not work\n");
00583 return(0);
00584 }
00585
00586 MemoryData(theEnv)->ChunkInfoSize = sizeof(struct chunkInfo);
00587 MemoryData(theEnv)->ChunkInfoSize = (int) ((((MemoryData(theEnv)->ChunkInfoSize - 1) / STRICT_ALIGN_SIZE) + 1) * STRICT_ALIGN_SIZE);
00588
00589 MemoryData(theEnv)->BlockInfoSize = sizeof(struct blockInfo);
00590 MemoryData(theEnv)->BlockInfoSize = (int) ((((MemoryData(theEnv)->BlockInfoSize - 1) / STRICT_ALIGN_SIZE) + 1) * STRICT_ALIGN_SIZE);
00591
00592 initialBlockSize = (INITBLOCKSIZE > requestSize ? INITBLOCKSIZE : requestSize);
00593 initialBlockSize += MemoryData(theEnv)->ChunkInfoSize * 2 + MemoryData(theEnv)->BlockInfoSize;
00594 initialBlockSize = (((initialBlockSize - 1) / STRICT_ALIGN_SIZE) + 1) * STRICT_ALIGN_SIZE;
00595
00596 usableBlockSize = initialBlockSize - (2 * MemoryData(theEnv)->ChunkInfoSize) - MemoryData(theEnv)->BlockInfoSize;
00597
00598
00599 if ((requestSize < INITBLOCKSIZE) &&
00600 (usableBlockSize <= requestSize + MemoryData(theEnv)->ChunkInfoSize))
00601 {
00602 initialBlockSize = requestSize + MemoryData(theEnv)->ChunkInfoSize * 2 + MemoryData(theEnv)->BlockInfoSize;
00603 initialBlockSize = (((initialBlockSize - 1) / STRICT_ALIGN_SIZE) + 1) * STRICT_ALIGN_SIZE;
00604 usableBlockSize = initialBlockSize - (2 * MemoryData(theEnv)->ChunkInfoSize) - MemoryData(theEnv)->BlockInfoSize;
00605 }
00606
00607 MemoryData(theEnv)->TopMemoryBlock = (struct blockInfo *) malloc((STD_SIZE) initialBlockSize);
00608
00609 if (MemoryData(theEnv)->TopMemoryBlock == NULL)
00610 {
00611 fprintf(stdout, "Unable to allocate initial memory pool\n");
00612 return(0);
00613 }
00614
00615 MemoryData(theEnv)->TopMemoryBlock->nextBlock = NULL;
00616 MemoryData(theEnv)->TopMemoryBlock->prevBlock = NULL;
00617 MemoryData(theEnv)->TopMemoryBlock->nextFree = (struct chunkInfo *) (((char *) MemoryData(theEnv)->TopMemoryBlock) + MemoryData(theEnv)->BlockInfoSize);
00618 MemoryData(theEnv)->TopMemoryBlock->size = (long) usableBlockSize;
00619
00620 chunkPtr = (struct chunkInfo *) (((char *) MemoryData(theEnv)->TopMemoryBlock) + MemoryData(theEnv)->BlockInfoSize + MemoryData(theEnv)->ChunkInfoSize + usableBlockSize);
00621 chunkPtr->nextFree = NULL;
00622 chunkPtr->lastFree = NULL;
00623 chunkPtr->prevChunk = MemoryData(theEnv)->TopMemoryBlock->nextFree;
00624 chunkPtr->size = 0;
00625
00626 MemoryData(theEnv)->TopMemoryBlock->nextFree->nextFree = NULL;
00627 MemoryData(theEnv)->TopMemoryBlock->nextFree->lastFree = NULL;
00628 MemoryData(theEnv)->TopMemoryBlock->nextFree->prevChunk = NULL;
00629 MemoryData(theEnv)->TopMemoryBlock->nextFree->size = (long) usableBlockSize;
00630
00631 MemoryData(theEnv)->BlockMemoryInitialized = TRUE;
00632 return(1);
00633 }
00634
00635
00636
00637
00638 static int AllocateBlock(
00639 void *theEnv,
00640 struct blockInfo *blockPtr,
00641 unsigned int requestSize)
00642 {
00643 unsigned int blockSize, usableBlockSize;
00644 struct blockInfo *newBlock;
00645 struct chunkInfo *newTopChunk;
00646
00647
00648
00649
00650
00651
00652
00653
00654 blockSize = (BLOCKSIZE > requestSize ? BLOCKSIZE : requestSize);
00655 blockSize += MemoryData(theEnv)->BlockInfoSize + MemoryData(theEnv)->ChunkInfoSize * 2;
00656 blockSize = (((blockSize - 1) / STRICT_ALIGN_SIZE) + 1) * STRICT_ALIGN_SIZE;
00657
00658 usableBlockSize = blockSize - MemoryData(theEnv)->BlockInfoSize - (2 * MemoryData(theEnv)->ChunkInfoSize);
00659
00660
00661
00662
00663
00664 newBlock = (struct blockInfo *) malloc((STD_SIZE) blockSize);
00665 if (newBlock == NULL) return(0);
00666
00667
00668
00669
00670
00671 newBlock->nextBlock = NULL;
00672 newBlock->prevBlock = blockPtr;
00673 newBlock->nextFree = (struct chunkInfo *) (((char *) newBlock) + MemoryData(theEnv)->BlockInfoSize);
00674 newBlock->size = (long) usableBlockSize;
00675 blockPtr->nextBlock = newBlock;
00676
00677 newTopChunk = (struct chunkInfo *) (((char *) newBlock) + MemoryData(theEnv)->BlockInfoSize + MemoryData(theEnv)->ChunkInfoSize + usableBlockSize);
00678 newTopChunk->nextFree = NULL;
00679 newTopChunk->lastFree = NULL;
00680 newTopChunk->size = 0;
00681 newTopChunk->prevChunk = newBlock->nextFree;
00682
00683 newBlock->nextFree->nextFree = NULL;
00684 newBlock->nextFree->lastFree = NULL;
00685 newBlock->nextFree->prevChunk = NULL;
00686 newBlock->nextFree->size = (long) usableBlockSize;
00687
00688 return(1);
00689 }
00690
00691
00692
00693
00694
00695 globle void *RequestChunk(
00696 void *theEnv,
00697 size_t requestSize)
00698 {
00699 struct chunkInfo *chunkPtr;
00700 struct blockInfo *blockPtr;
00701
00702
00703
00704
00705
00706
00707 if (MemoryData(theEnv)->BlockMemoryInitialized == FALSE)
00708 {
00709 if (InitializeBlockMemory(theEnv,requestSize) == 0) return(NULL);
00710 }
00711
00712
00713
00714
00715
00716
00717 requestSize = (((requestSize - 1) / STRICT_ALIGN_SIZE) + 1) * STRICT_ALIGN_SIZE;
00718
00719
00720
00721
00722
00723
00724
00725 blockPtr = MemoryData(theEnv)->TopMemoryBlock;
00726
00727 while (blockPtr != NULL)
00728 {
00729 chunkPtr = blockPtr->nextFree;
00730
00731 while (chunkPtr != NULL)
00732 {
00733 if ((chunkPtr->size == requestSize) ||
00734 (chunkPtr->size > (requestSize + MemoryData(theEnv)->ChunkInfoSize)))
00735 {
00736 AllocateChunk(theEnv,blockPtr,chunkPtr,requestSize);
00737
00738 return((void *) (((char *) chunkPtr) + MemoryData(theEnv)->ChunkInfoSize));
00739 }
00740 chunkPtr = chunkPtr->nextFree;
00741 }
00742
00743 if (blockPtr->nextBlock == NULL)
00744 {
00745 if (AllocateBlock(theEnv,blockPtr,requestSize) == 0)
00746 { return(NULL); }
00747 }
00748 blockPtr = blockPtr->nextBlock;
00749 }
00750
00751 SystemError(theEnv,"MEMORY",2);
00752 EnvExitRouter(theEnv,EXIT_FAILURE);
00753 return(NULL);
00754 }
00755
00756
00757
00758
00759
00760 static void AllocateChunk(
00761 void *theEnv,
00762 struct blockInfo *parentBlock,
00763 struct chunkInfo *chunkPtr,
00764 size_t requestSize)
00765 {
00766 struct chunkInfo *splitChunk, *nextChunk;
00767
00768
00769
00770
00771
00772
00773
00774 if (requestSize == chunkPtr->size)
00775 {
00776 chunkPtr->size = - (long int) requestSize;
00777 if (chunkPtr->lastFree == NULL)
00778 {
00779 if (chunkPtr->nextFree != NULL)
00780 { parentBlock->nextFree = chunkPtr->nextFree; }
00781 else
00782 { parentBlock->nextFree = NULL; }
00783 }
00784 else
00785 { chunkPtr->lastFree->nextFree = chunkPtr->nextFree; }
00786
00787 if (chunkPtr->nextFree != NULL)
00788 { chunkPtr->nextFree->lastFree = chunkPtr->lastFree; }
00789
00790 chunkPtr->lastFree = NULL;
00791 chunkPtr->nextFree = NULL;
00792 return;
00793 }
00794
00795
00796
00797
00798
00799
00800 nextChunk = (struct chunkInfo *)
00801 (((char *) chunkPtr) + MemoryData(theEnv)->ChunkInfoSize + chunkPtr->size);
00802
00803 splitChunk = (struct chunkInfo *)
00804 (((char *) chunkPtr) + (MemoryData(theEnv)->ChunkInfoSize + requestSize));
00805
00806 splitChunk->size = (long) (chunkPtr->size - (requestSize + MemoryData(theEnv)->ChunkInfoSize));
00807 splitChunk->prevChunk = chunkPtr;
00808
00809 splitChunk->nextFree = chunkPtr->nextFree;
00810 splitChunk->lastFree = chunkPtr->lastFree;
00811
00812 nextChunk->prevChunk = splitChunk;
00813
00814 if (splitChunk->lastFree == NULL)
00815 { parentBlock->nextFree = splitChunk; }
00816 else
00817 { splitChunk->lastFree->nextFree = splitChunk; }
00818
00819 if (splitChunk->nextFree != NULL)
00820 { splitChunk->nextFree->lastFree = splitChunk; }
00821
00822 chunkPtr->size = - (long int) requestSize;
00823 chunkPtr->lastFree = NULL;
00824 chunkPtr->nextFree = NULL;
00825
00826 return;
00827 }
00828
00829
00830
00831
00832 globle int ReturnChunk(
00833 void *theEnv,
00834 void *memPtr,
00835 size_t size)
00836 {
00837 struct chunkInfo *chunkPtr, *lastChunk, *nextChunk, *topChunk;
00838 struct blockInfo *blockPtr;
00839
00840
00841
00842
00843
00844
00845 size = (((size - 1) / STRICT_ALIGN_SIZE) + 1) * STRICT_ALIGN_SIZE;
00846
00847 chunkPtr = (struct chunkInfo *) (((char *) memPtr) - MemoryData(theEnv)->ChunkInfoSize);
00848
00849 if (chunkPtr == NULL)
00850 { return(FALSE); }
00851
00852 if (chunkPtr->size >= 0)
00853 { return(FALSE); }
00854
00855 if (chunkPtr->size != - (long int) size)
00856 { return(FALSE); }
00857
00858 chunkPtr->size = - chunkPtr->size;
00859
00860
00861
00862
00863
00864 topChunk = chunkPtr;
00865 while (topChunk->prevChunk != NULL)
00866 { topChunk = topChunk->prevChunk; }
00867 blockPtr = (struct blockInfo *) (((char *) topChunk) - MemoryData(theEnv)->BlockInfoSize);
00868
00869
00870
00871
00872
00873
00874 lastChunk = chunkPtr->prevChunk;
00875 nextChunk = (struct chunkInfo *) (((char *) memPtr) + size);
00876
00877
00878
00879
00880
00881 if (blockPtr->nextFree != NULL)
00882 { blockPtr->nextFree->lastFree = chunkPtr; }
00883
00884 chunkPtr->nextFree = blockPtr->nextFree;
00885 chunkPtr->lastFree = NULL;
00886
00887 blockPtr->nextFree = chunkPtr;
00888
00889
00890
00891
00892
00893 if (lastChunk != NULL)
00894 {
00895 if (lastChunk->size > 0)
00896 {
00897 lastChunk->size += (MemoryData(theEnv)->ChunkInfoSize + chunkPtr->size);
00898
00899 if (nextChunk != NULL)
00900 { nextChunk->prevChunk = lastChunk; }
00901 else
00902 { return(FALSE); }
00903
00904 if (lastChunk->lastFree != NULL)
00905 { lastChunk->lastFree->nextFree = lastChunk->nextFree; }
00906
00907 if (lastChunk->nextFree != NULL)
00908 { lastChunk->nextFree->lastFree = lastChunk->lastFree; }
00909
00910 lastChunk->nextFree = chunkPtr->nextFree;
00911 if (chunkPtr->nextFree != NULL)
00912 { chunkPtr->nextFree->lastFree = lastChunk; }
00913 lastChunk->lastFree = NULL;
00914
00915 blockPtr->nextFree = lastChunk;
00916 chunkPtr->lastFree = NULL;
00917 chunkPtr->nextFree = NULL;
00918 chunkPtr = lastChunk;
00919 }
00920 }
00921
00922
00923
00924
00925
00926 if (nextChunk == NULL) return(FALSE);
00927 if (chunkPtr == NULL) return(FALSE);
00928
00929 if (nextChunk->size > 0)
00930 {
00931 chunkPtr->size += (MemoryData(theEnv)->ChunkInfoSize + nextChunk->size);
00932
00933 topChunk = (struct chunkInfo *) (((char *) nextChunk) + nextChunk->size + MemoryData(theEnv)->ChunkInfoSize);
00934 if (topChunk != NULL)
00935 { topChunk->prevChunk = chunkPtr; }
00936 else
00937 { return(FALSE); }
00938
00939 if (nextChunk->lastFree != NULL)
00940 { nextChunk->lastFree->nextFree = nextChunk->nextFree; }
00941
00942 if (nextChunk->nextFree != NULL)
00943 { nextChunk->nextFree->lastFree = nextChunk->lastFree; }
00944
00945 }
00946
00947
00948
00949
00950
00951
00952 if ((chunkPtr->prevChunk == NULL) &&
00953 (chunkPtr->size == blockPtr->size))
00954 {
00955 if (blockPtr->prevBlock != NULL)
00956 {
00957 blockPtr->prevBlock->nextBlock = blockPtr->nextBlock;
00958 if (blockPtr->nextBlock != NULL)
00959 { blockPtr->nextBlock->prevBlock = blockPtr->prevBlock; }
00960 free((char *) blockPtr);
00961 }
00962 else
00963 {
00964 if (blockPtr->nextBlock != NULL)
00965 {
00966 blockPtr->nextBlock->prevBlock = NULL;
00967 MemoryData(theEnv)->TopMemoryBlock = blockPtr->nextBlock;
00968 free((char *) blockPtr);
00969 }
00970 }
00971 }
00972
00973 return(TRUE);
00974 }
00975
00976
00977
00978
00979
00980 globle void ReturnAllBlocks(
00981 void *theEnv)
00982 {
00983 struct blockInfo *theBlock, *nextBlock;
00984
00985
00986
00987
00988
00989 theBlock = MemoryData(theEnv)->TopMemoryBlock;
00990 while (theBlock != NULL)
00991 {
00992 nextBlock = theBlock->nextBlock;
00993 free((char *) theBlock);
00994 theBlock = nextBlock;
00995 }
00996
00997 MemoryData(theEnv)->TopMemoryBlock = NULL;
00998 }
00999 #endif