Back to index

plt-scheme  4.2.1
MacOS.c
Go to the documentation of this file.
00001 /*
00002        MacOS.c
00003        
00004        Some routines for the Macintosh OS port of the Hans-J. Boehm, Alan J. Demers
00005        garbage collector.
00006        
00007        <Revision History>
00008        
00009        11/22/94  pcb  StripAddress the temporary memory handle for 24-bit mode.
00010        11/30/94  pcb  Tracking all memory usage so we can deallocate it all at once.
00011        02/10/96  pcb  Added routine to perform a final collection when
00012 unloading shared library.
00013        
00014        by Patrick C. Beard.
00015  */
00016 /* Boehm, February 15, 1996 2:55 pm PST */
00017 
00018 #include <Resources.h>
00019 #include <Memory.h>
00020 #include <LowMem.h>
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <string.h>
00024 
00025 #include "gc.h"
00026 #include "gc_priv.h"
00027 
00028 // use 'CODE' resource 0 to get exact location of the beginning of global space.
00029 
00030 typedef struct {
00031        unsigned long aboveA5;
00032        unsigned long belowA5;
00033        unsigned long JTSize;
00034        unsigned long JTOffset;
00035 } *CodeZeroPtr, **CodeZeroHandle;
00036 
00037 void* GC_MacGetDataStart()
00038 {
00039        CodeZeroHandle code0 = (CodeZeroHandle)GetResource('CODE', 0);
00040        if (code0) {
00041               long belowA5Size = (**code0).belowA5;
00042               ReleaseResource((Handle)code0);
00043               return (LMGetCurrentA5() - belowA5Size);
00044        }
00045        fprintf(stderr, "Couldn't load the jump table.");
00046        exit(-1);
00047        return 0;
00048 }
00049 
00050 /* track the use of temporary memory so it can be freed all at once. */
00051 
00052 typedef struct TemporaryMemoryBlock TemporaryMemoryBlock, **TemporaryMemoryHandle;
00053 
00054 struct TemporaryMemoryBlock {
00055        TemporaryMemoryHandle nextBlock;
00056        char data[];
00057 };
00058 
00059 static TemporaryMemoryHandle theTemporaryMemory = NULL;
00060 static Boolean firstTime = true;
00061 
00062 void GC_MacFreeTemporaryMemory(void);
00063 
00064 Ptr GC_MacTemporaryNewPtr(size_t size, Boolean clearMemory)
00065 {
00066        static Boolean firstTime = true;
00067        OSErr result;
00068        TemporaryMemoryHandle tempMemBlock;
00069        Ptr tempPtr = nil;
00070 
00071        tempMemBlock = (TemporaryMemoryHandle)TempNewHandle(size + sizeof(TemporaryMemoryBlock), &result);
00072        if (tempMemBlock && result == noErr) {
00073               HLockHi((Handle)tempMemBlock);
00074               tempPtr = (**tempMemBlock).data;
00075               if (clearMemory) memset(tempPtr, 0, size);
00076               tempPtr = StripAddress(tempPtr);
00077 
00078               // keep track of the allocated blocks.
00079               (**tempMemBlock).nextBlock = theTemporaryMemory;
00080               theTemporaryMemory = tempMemBlock;
00081        }
00082        
00083 #     if !defined(SHARED_LIBRARY_BUILD)
00084        // install an exit routine to clean up the memory used at the end.
00085        if (firstTime) {
00086               atexit(&GC_MacFreeTemporaryMemory);
00087               firstTime = false;
00088        }
00089 #     endif
00090        
00091        return tempPtr;
00092 }
00093 
00094 extern word GC_fo_entries; 
00095 
00096 static void perform_final_collection()
00097 {
00098   unsigned i;
00099   word last_fo_entries = 0;
00100   
00101   /* adjust the stack bottom, because CFM calls us from another stack
00102      location. */
00103      GC_stackbottom = (ptr_t)&i;
00104 
00105   /* try to collect and finalize everything in sight */
00106     for (i = 0; i < 2 || GC_fo_entries < last_fo_entries; i++) {
00107         last_fo_entries = GC_fo_entries;
00108         GC_gcollect();
00109     }
00110 }
00111 
00112 
00113 void GC_MacFreeTemporaryMemory()
00114 {
00115 # if defined(SHARED_LIBRARY_BUILD)
00116     /* if possible, collect all memory, and invoke all finalizers. */
00117       perform_final_collection();
00118 # endif
00119 
00120     if (theTemporaryMemory != NULL) {
00121        long totalMemoryUsed = 0;
00122        TemporaryMemoryHandle tempMemBlock = theTemporaryMemory;
00123        while (tempMemBlock != NULL) {
00124               TemporaryMemoryHandle nextBlock = (**tempMemBlock).nextBlock;
00125               totalMemoryUsed += GetHandleSize((Handle)tempMemBlock);
00126               DisposeHandle((Handle)tempMemBlock);
00127               tempMemBlock = nextBlock;
00128        }
00129        theTemporaryMemory = NULL;
00130 
00131 #       if !defined(SILENT) && !defined(SHARED_LIBRARY_BUILD)
00132           fprintf(stdout, "[total memory used:  %ld bytes.]\n",
00133                   totalMemoryUsed);
00134           fprintf(stdout, "[total collections:  %ld.]\n", GC_gc_no);
00135 #       endif
00136     }
00137 }
00138 
00139 #if __option(far_data)
00140 
00141   void* GC_MacGetDataEnd()
00142   {
00143        CodeZeroHandle code0 = (CodeZeroHandle)GetResource('CODE', 0);
00144        if (code0) {
00145               long aboveA5Size = (**code0).aboveA5;
00146               ReleaseResource((Handle)code0);
00147               return (LMGetCurrentA5() + aboveA5Size);
00148        }
00149        fprintf(stderr, "Couldn't load the jump table.");
00150        exit(-1);
00151        return 0;
00152   }
00153 
00154 #endif /* __option(far_data) */