Otherwise a poorly timed GC can collect the memory before it
is returned to the Go program.
R=golang-dev, dave, dvyukov, minux.ma
CC=golang-dev
https://golang.org/cl/
6819119
static void
_cgo_allocate_internal(uintptr len, byte *ret)
{
+ CgoMal *c;
+
ret = runtime·mal(len);
+ c = runtime·mal(sizeof(*c));
+ c->next = m->cgomal;
+ c->alloc = ret;
+ m->cgomal = c;
FLUSH(&ret);
}
g->defer = &d;
}
+ m->ncgo++;
+
/*
* Announce we are entering a system call
* so that the scheduler knows to create another
runtime·asmcgocall(fn, arg);
runtime·exitsyscall();
+ m->ncgo--;
+ if(m->ncgo == 0) {
+ // We are going back to Go and are not in a recursive
+ // call. Let the GC collect any memory allocated via
+ // _cgo_allocate that is no longer referenced.
+ m->cgomal = nil;
+ }
+
if(d.nofree) {
if(g->defer != &d || d.fn != (byte*)unlockm)
runtime·throw("runtime: bad defer entry in cgocallback");
typedef struct LFNode LFNode;
typedef struct ParFor ParFor;
typedef struct ParForThread ParForThread;
+typedef struct CgoMal CgoMal;
/*
* Per-CPU declaration.
int32 profilehz;
int32 helpgc;
uint32 fastrand;
- uint64 ncgocall;
+ uint64 ncgocall; // number of cgo calls in total
+ int32 ncgo; // number of cgo calls currently in progress
+ CgoMal* cgomal;
Note havenextg;
G* nextg;
M* alllink; // on allm
uint64 nsleep;
};
+// Track memory allocated by code not written in Go during a cgo call,
+// so that the garbage collector can see them.
+struct CgoMal
+{
+ CgoMal *next;
+ byte *alloc;
+};
+
/*
* defined macros
* you need super-gopher-guru privilege