mirror of
https://github.com/golang/go
synced 2024-11-19 21:04:43 -07:00
runtime, runtime/cgo: track memory allocated by non-Go code
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
This commit is contained in:
parent
5612edb13e
commit
e9a3087e29
@ -33,7 +33,13 @@
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -135,6 +135,8 @@ runtime·cgocall(void (*fn)(void*), void *arg)
|
||||
g->defer = &d;
|
||||
}
|
||||
|
||||
m->ncgo++;
|
||||
|
||||
/*
|
||||
* Announce we are entering a system call
|
||||
* so that the scheduler knows to create another
|
||||
@ -150,6 +152,14 @@ runtime·cgocall(void (*fn)(void*), void *arg)
|
||||
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");
|
||||
|
@ -81,6 +81,7 @@ typedef struct GCStats GCStats;
|
||||
typedef struct LFNode LFNode;
|
||||
typedef struct ParFor ParFor;
|
||||
typedef struct ParForThread ParForThread;
|
||||
typedef struct CgoMal CgoMal;
|
||||
|
||||
/*
|
||||
* Per-CPU declaration.
|
||||
@ -249,7 +250,9 @@ struct M
|
||||
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
|
||||
@ -414,6 +417,14 @@ struct ParFor
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user