diff options
Diffstat (limited to 'graphics/asymptote/gc/extra/MacOS.c')
-rw-r--r-- | graphics/asymptote/gc/extra/MacOS.c | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/graphics/asymptote/gc/extra/MacOS.c b/graphics/asymptote/gc/extra/MacOS.c new file mode 100644 index 0000000000..082ee6ed7c --- /dev/null +++ b/graphics/asymptote/gc/extra/MacOS.c @@ -0,0 +1,169 @@ +/* + MacOS.c + + Some routines for the Macintosh OS port of the Hans-J. Boehm, Alan J. Demers + garbage collector. + + <Revision History> + + 11/22/94 pcb StripAddress the temporary memory handle for 24-bit mode. + 11/30/94 pcb Tracking all memory usage so we can deallocate it all at once. + 02/10/96 pcb Added routine to perform a final collection when +unloading shared library. + + by Patrick C. Beard. + */ +/* Boehm, February 15, 1996 2:55 pm PST */ + +#include <Resources.h> +#include <Memory.h> +#include <LowMem.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define GC_BUILD +#include "gc.h" +#include "private/gc_priv.h" + +/* use 'CODE' resource 0 to get exact location of the beginning of global space. */ + +typedef struct { + unsigned long aboveA5; + unsigned long belowA5; + unsigned long JTSize; + unsigned long JTOffset; +} *CodeZeroPtr, **CodeZeroHandle; + +void* GC_MacGetDataStart(void) +{ + CodeZeroHandle code0 = (CodeZeroHandle)GetResource('CODE', 0); + if (code0) { + long belowA5Size = (**code0).belowA5; + ReleaseResource((Handle)code0); + return (LMGetCurrentA5() - belowA5Size); + } + fprintf(stderr, "Couldn't load the jump table."); + exit(-1); +# if !defined(CPPCHECK) + return 0; /* to avoid compiler complain about missing return */ +# endif +} + +#ifdef USE_TEMPORARY_MEMORY + +/* track the use of temporary memory so it can be freed all at once. */ + +typedef struct TemporaryMemoryBlock TemporaryMemoryBlock, **TemporaryMemoryHandle; + +struct TemporaryMemoryBlock { + TemporaryMemoryHandle nextBlock; + char data[]; +}; + +static TemporaryMemoryHandle theTemporaryMemory = NULL; + +void GC_MacFreeTemporaryMemory(void); + +Ptr GC_MacTemporaryNewPtr(size_t size, Boolean clearMemory) +{ +# if !defined(SHARED_LIBRARY_BUILD) + static Boolean firstTime = true; +# endif + OSErr result; + TemporaryMemoryHandle tempMemBlock; + Ptr tempPtr = nil; + + tempMemBlock = (TemporaryMemoryHandle)TempNewHandle(size + sizeof(TemporaryMemoryBlock), &result); + if (tempMemBlock && result == noErr) { + HLockHi((Handle)tempMemBlock); + tempPtr = (**tempMemBlock).data; + if (clearMemory) memset(tempPtr, 0, size); + tempPtr = StripAddress(tempPtr); + + /* keep track of the allocated blocks. */ + (**tempMemBlock).nextBlock = theTemporaryMemory; + theTemporaryMemory = tempMemBlock; + } + +# if !defined(SHARED_LIBRARY_BUILD) + /* install an exit routine to clean up the memory used at the end. */ + if (firstTime) { + atexit(&GC_MacFreeTemporaryMemory); + firstTime = false; + } +# endif + + return tempPtr; +} + +static void perform_final_collection(void) +{ + unsigned i; + word last_fo_entries = 0; + + /* adjust the stack bottom, because CFM calls us from another stack + location. */ + GC_stackbottom = (ptr_t)&i; + + /* try to collect and finalize everything in sight */ + for (i = 0; i < 2 || GC_fo_entries < last_fo_entries; i++) { + last_fo_entries = GC_fo_entries; + GC_gcollect(); + } +} + + +void GC_MacFreeTemporaryMemory(void) +{ +# if defined(SHARED_LIBRARY_BUILD) + /* if possible, collect all memory, and invoke all finalizers. */ + perform_final_collection(); +# endif + + if (theTemporaryMemory != NULL) { +# if !defined(SHARED_LIBRARY_BUILD) + long totalMemoryUsed = 0; +# endif + TemporaryMemoryHandle tempMemBlock = theTemporaryMemory; + while (tempMemBlock /* != NULL */) { + TemporaryMemoryHandle nextBlock = (**tempMemBlock).nextBlock; +# if !defined(SHARED_LIBRARY_BUILD) + totalMemoryUsed += GetHandleSize((Handle)tempMemBlock); +# endif + DisposeHandle((Handle)tempMemBlock); + tempMemBlock = nextBlock; + } + theTemporaryMemory = NULL; + +# if !defined(SHARED_LIBRARY_BUILD) + if (GC_print_stats) { + fprintf(stdout, "[total memory used: %ld bytes.]\n", + totalMemoryUsed); + fprintf(stdout, "[total collections: %lu]\n", + (unsigned long)GC_gc_no); + } +# endif + } +} + +#endif /* USE_TEMPORARY_MEMORY */ + +#if __option(far_data) + + void* GC_MacGetDataEnd(void) + { + CodeZeroHandle code0 = (CodeZeroHandle)GetResource('CODE', 0); + if (code0) { + long aboveA5Size = (**code0).aboveA5; + ReleaseResource((Handle)code0); + return (LMGetCurrentA5() + aboveA5Size); + } + fprintf(stderr, "Couldn't load the jump table."); + exit(-1); +# if !defined(CPPCHECK) + return 0; +# endif + } + +#endif /* __option(far_data) */ |