Skip to content

Commit

Permalink
Handle negative pointer in garbage collector
Browse files Browse the repository at this point in the history
Previously, the garbage collection in `mgc.x` used two pseudo values for
organizational issues: implicitly initialized NULL for the end of the `MGC`
buffer, and negative values for pointers that are already freed.

Since pointers may be negative (they are relative to the `Mem` common block),
this patch changes this behaviour: we now use NULL for pointers that are
already freed, and an additional variable `bmax` in the `/nmemio/` common
block to determine current the end of the `MGC` buffer.

Note that this could not be fully tested, since the garbage collector
is active only when the environment variable `MEMIO_COLLECT` is set to
1. This mode is however already buggy with the precompiled version
2.16.1:

```
$ MEMIO_COLLECT=1 cl
setting terminal type to 'xgterm' ...

PANIC in `/iraf/iraf/bin/64/bin.linux64/x_system.e': invalid SET in IRAF Main
```
  • Loading branch information
olebole committed Oct 15, 2017
1 parent a22dcfe commit 7e582ab
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 27 deletions.
42 changes: 16 additions & 26 deletions sys/nmemio/mgc.x
Expand Up @@ -6,8 +6,8 @@ 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.
# freed the pointer value is set to NULL 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
Expand Down Expand Up @@ -64,21 +64,22 @@ procedure mgc_save (ptr, dtype)
pointer ptr #i pointer to save
int dtype #i pointer type

int i, bmax
int i

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.
for (i=0; i < SZ_GC_BUFFER - 1; i=i+1) {
if (GC_PTR(mgc,i) == NULL) {
# Either already freed slot, or the first free one
GC_PTR(mgc,i) = ptr
GC_TYPE(mgc,i) = dtype

if (bmax < i) {
bmax = i
}
if (mdebug > 0) {
call eprintf ("save %d: ptr 0x%x\n")
call pargi (i); call pargi (GC_PTR(mgc,i))
Expand All @@ -101,7 +102,7 @@ procedure mgc_update (ptr)
pointer ptr #i pointer to save
int i, bmax
int i
include "nmemio.com"
Expand All @@ -115,18 +116,15 @@ begin
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)
GC_PTR(mgc,i) = NULL
return
}
if (GC_PTR(mgc,i) == NULL)
return
}
end
Expand All @@ -137,20 +135,17 @@ int procedure mgc_getindex (ptr)
pointer ptr #i pointer to save
int i, bmax
int i
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)
Expand All @@ -163,20 +158,17 @@ int procedure mgc_gettype (ptr)
pointer ptr #i pointer to save
int i, bmax
int i
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)
Expand All @@ -187,7 +179,7 @@ end
procedure mgc_collect ()
int i, bmax, nchars
int i, nchars
pointer bp
int sizeof ()
Expand All @@ -200,9 +192,8 @@ begin
return
mcollect = -1
bmax = SZ_GC_BUFFER - 1
do i = 0, bmax {
if (GC_PTR(mgc,i) > 0) {
if (GC_PTR(mgc,i) != NULL) {
if (mdebug > 0) {
call eprintf ("collect %d: recovering ptr 0x%x\n")
call pargi (i); call pargi (GC_PTR(mgc,i))
Expand All @@ -216,7 +207,6 @@ begin
call mfree (GC_PTR(mgc,i), GC_TYPE(mgc,i))
} else if (GC_PTR(mgc,i) == NULL)
return
}
}
end
1 change: 1 addition & 0 deletions sys/nmemio/minit.x
Expand Up @@ -44,6 +44,7 @@ begin
nleaked = 0
nalloc = 0
nfree = 0
bmax = 0

in_task = 1
end
Expand Down
3 changes: 2 additions & 1 deletion sys/nmemio/nmemio.com
Expand Up @@ -17,10 +17,11 @@ int nfree # total number of frees
int mdebug # debugging memory use in tasks?
int in_task # in task or iraf main?

int bmax # current maximum number of pointers
pointer mgc # garbage collection buffer

# Debug common
common /nmemio/ mclear, mwatch, mcollect, mreport, lsentinal, usentinal,
mem_used, max_alloc, nleaked, leaked, nalloc, nfree,
mdebug, in_task, mgc
mdebug, in_task, bmax, mgc

0 comments on commit 7e582ab

Please sign in to comment.