aboutsummaryrefslogtreecommitdiff
path: root/sys/nmemio/mgc.x
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
commitfa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 (patch)
treebdda434976bc09c864f2e4fa6f16ba1952b1e555 /sys/nmemio/mgc.x
downloadiraf-linux-fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4.tar.gz
Initial commit
Diffstat (limited to 'sys/nmemio/mgc.x')
-rw-r--r--sys/nmemio/mgc.x222
1 files changed, 222 insertions, 0 deletions
diff --git a/sys/nmemio/mgc.x b/sys/nmemio/mgc.x
new file mode 100644
index 00000000..8ef2b58c
--- /dev/null
+++ b/sys/nmemio/mgc.x
@@ -0,0 +1,222 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <mach.h>
+
+
+# MGC Interface - Simple memory garbage collector interface. Our strategy
+# here is simply to store the pointer and its type (so we can dereference to
+# a host pointer). As pointers are allocated they are saved here, and when
+# freed the pointer value is made negative to indicate it is invalid and
+# that slot is available for later reuse.
+# When a task completes, we run through the buffer looking for un-freed
+# pointers and manually reclaim the space. This is not especially clever but
+# we are only used (presumably by developers) when requested so normal use
+# of MEMIO should see no added overhead.
+#
+# mgc_init ()
+# mgc_close ()
+# mgc_save (ptr, dtype)
+# mgc_update (ptr)
+# index = mgc_getindex (ptr)
+# type = mgc_gettype (ptr)
+# mgc_collect ()
+
+
+define SZ_GC_BUFFER 10240
+
+# A zero-indexed structure saving the (ptr,type) pairs.
+define GC_PTR Memi[$1+($2 * 2)]
+define GC_TYPE Memi[$1+($2 * 2 + 1)]
+
+
+# MGC_INIT -- Initialize the MGC interface.
+
+procedure mgc_init ()
+
+include "nmemio.com"
+
+begin
+ if (mcollect > 0)
+ call calloc (mgc, SZ_GC_BUFFER, TY_STRUCT)
+ else
+ mgc = NULL
+end
+
+
+# MGC_CLOSE -- Close the MGC buffer.
+
+procedure mgc_close ()
+
+include "nmemio.com"
+
+begin
+ if (mcollect > 0 && mgc != NULL) {
+ call mfree (mgc, TY_STRUCT)
+ mgc = NULL
+ }
+end
+
+
+# MGC_SAVE -- Save a pointer in the GC buffer.
+
+procedure mgc_save (ptr, dtype)
+
+pointer ptr #i pointer to save
+int dtype #i pointer type
+
+int i, bmax
+
+include "nmemio.com"
+
+begin
+ if (mcollect <= 0 || mgc == NULL)
+ return
+
+ bmax = SZ_GC_BUFFER - 1
+ for (i=0; i < bmax; i=i+1) {
+ if (GC_PTR(mgc,i) <= 0) {
+ # Space is re-used if negative, otherwise first free slot.
+ GC_PTR(mgc,i) = ptr
+ GC_TYPE(mgc,i) = dtype
+
+ if (mdebug > 0) {
+ call eprintf ("save %d: ptr 0x%x\n")
+ call pargi (i); call pargi (GC_PTR(mgc,i))
+ }
+ return
+ }
+ }
+
+ # If we get this far we've exhausted the GC buffer. Print a warning
+ # if reporting and just ignore it since the chances this would be
+ # a leaked pointer are rather small.
+ if (mreport > 0)
+ call eprintf ("Warning: GC buffer overflow\n")
+end
+
+
+# MGC_UPDATE -- Update the status of the pointer in the GC buffer.
+
+procedure mgc_update (ptr)
+
+pointer ptr #i pointer to save
+
+int i, bmax
+
+include "nmemio.com"
+
+begin
+ if (mgc == NULL || in_task == 0)
+ return
+
+ if (in_task > 0 && mdebug > 0) {
+ call eprintf ("update 0x%x collect = %d\n")
+ call pargi (ptr)
+ call pargi (mcollect)
+ }
+
+ bmax = SZ_GC_BUFFER - 1
+ do i = 0, bmax {
+ if (GC_PTR(mgc,i) == ptr) {
+ if (in_task > 0 && mdebug > 0) {
+ call eprintf ("update %d: 0x%x %d\n")
+ call pargi (i); call pargi (GC_PTR(mgc,i)); call pargi (ptr)
+ }
+ GC_PTR(mgc,i) = (- ptr)
+ return
+ }
+ if (GC_PTR(mgc,i) == NULL)
+ return
+ }
+end
+
+
+# MGC_GETINDEX -- Given a pointer, return its GC index.
+
+int procedure mgc_getindex (ptr)
+
+pointer ptr #i pointer to save
+
+int i, bmax
+
+include "nmemio.com"
+
+begin
+ if (mcollect <= 0 || mgc == NULL)
+ return
+
+ bmax = SZ_GC_BUFFER - 1
+ do i = 0, bmax {
+ if (abs (GC_PTR(mgc,i)) == ptr)
+ return (i)
+ if (GC_PTR(mgc,i) == NULL)
+ return (NULL)
+ }
+
+ return (NULL)
+end
+
+
+# MGC_GETTYPE -- Given a pointer, return its type.
+
+int procedure mgc_gettype (ptr)
+
+pointer ptr #i pointer to save
+
+int i, bmax
+
+include "nmemio.com"
+
+begin
+ if (mcollect <= 0 || mgc == NULL)
+ return
+
+ bmax = SZ_GC_BUFFER - 1
+ do i = 0, bmax {
+ if (abs (GC_PTR(mgc,i)) == ptr)
+ return (GC_TYPE(mgc,i))
+ if (GC_PTR(mgc,i) == NULL)
+ return (NULL)
+ }
+
+ return (NULL)
+end
+
+
+# MGC_COLLECT -- Do the final garbage collection.
+
+procedure mgc_collect ()
+
+int i, bmax, nchars
+pointer bp
+
+int sizeof ()
+pointer coerce ()
+
+include "nmemio.com"
+
+begin
+ if (mcollect <= 0 || mgc == NULL)
+ return
+ mcollect = -1
+
+ bmax = SZ_GC_BUFFER - 1
+ do i = 0, bmax {
+ if (GC_PTR(mgc,i) > 0) {
+ if (mdebug > 0) {
+ call eprintf ("collect %d: recovering ptr 0x%x\n")
+ call pargi (i); call pargi (GC_PTR(mgc,i))
+ }
+
+ bp = coerce (GC_PTR(mgc,i), GC_TYPE(mgc,i), TY_INT)
+
+ nleaked = nleaked + 1
+ nchars = Memi[bp - 2] * sizeof (GC_TYPE(mgc,i))
+ leaked = leaked + (nchars * SZB_CHAR)
+
+ call mfree (GC_PTR(mgc,i), GC_TYPE(mgc,i))
+
+ } else if (GC_PTR(mgc,i) == NULL)
+ return
+ }
+end