Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
7bea4023
Commit
7bea4023
authored
Jun 04, 2012
by
Ian Lance Taylor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
runtime: Better SWIG interface for allocating Go memory from C/C++.
From-SVN: r188164
parent
7b4cf266
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
149 additions
and
3 deletions
+149
-3
libgo/go/syscall/libcall_support.go
+6
-0
libgo/runtime/go-cgo.c
+139
-3
libgo/runtime/runtime.h
+4
-0
No files found.
libgo/go/syscall/libcall_support.go
View file @
7bea4023
...
...
@@ -10,3 +10,9 @@ func Entersyscall()
func
Exitsyscall
()
func
GetErrno
()
Errno
func
SetErrno
(
Errno
)
// These functions are used by CGO and SWIG.
func
Cgocall
()
func
CgocallDone
()
func
CgocallBack
()
func
CgocallBackDone
()
libgo/runtime/go-cgo.c
View file @
7bea4023
...
...
@@ -4,11 +4,116 @@
Use of this source code is governed by a BSD-style
license that can be found in the LICENSE file. */
#include "runtime.h"
#include "go-alloc.h"
#include "interface.h"
#include "go-panic.h"
#include "go-string.h"
/* Go memory allocated by code not written in Go. We keep a linked
list of these allocations so that the garbage collector can see
them. */
struct
cgoalloc
{
struct
cgoalloc
*
next
;
void
*
alloc
;
};
/* Prepare to call from code written in Go to code written in C or
C++. This takes the current goroutine out of the Go scheduler, as
though it were making a system call. Otherwise the program can
lock up if the C code goes to sleep on a mutex or for some other
reason. This idea is to call this function, then immediately call
the C/C++ function. After the C/C++ function returns, call
syscall_cgocalldone. The usual Go code would look like
syscall.Cgocall()
defer syscall.Cgocalldone()
cfunction()
*/
/* We let Go code call these via the syscall package. */
void
syscall_cgocall
(
void
)
__asm__
(
"syscall.Cgocall"
);
void
syscall_cgocalldone
(
void
)
__asm__
(
"syscall.CgocallDone"
);
void
syscall_cgocallback
(
void
)
__asm__
(
"syscall.CgocallBack"
);
void
syscall_cgocallbackdone
(
void
)
__asm__
(
"syscall.CgocallBackDone"
);
void
syscall_cgocall
()
{
M
*
m
;
G
*
g
;
m
=
runtime_m
();
++
m
->
ncgocall
;
g
=
runtime_g
();
++
g
->
ncgo
;
runtime_entersyscall
();
}
/* Prepare to return to Go code from C/C++ code. */
void
syscall_cgocalldone
()
{
G
*
g
;
g
=
runtime_g
();
__go_assert
(
g
!=
NULL
);
--
g
->
ncgo
;
if
(
g
->
ncgo
==
0
)
{
/* We are going back to Go, and we are not in a recursive call.
Let the garbage collector clean up any unreferenced
memory. */
g
->
cgoalloc
=
NULL
;
}
/* If we are invoked because the C function called _cgo_panic, then
_cgo_panic will already have exited syscall mode. */
if
(
g
->
status
==
Gsyscall
)
runtime_exitsyscall
();
}
/* Call back from C/C++ code to Go code. */
void
syscall_cgocallback
()
{
runtime_exitsyscall
();
}
/* Prepare to return to C/C++ code from a callback to Go code. */
void
syscall_cgocallbackdone
()
{
runtime_entersyscall
();
}
/* Allocate memory and save it in a list visible to the Go garbage
collector. */
void
*
alloc_saved
(
size_t
n
)
{
void
*
ret
;
G
*
g
;
struct
cgoalloc
*
c
;
ret
=
__go_alloc
(
n
);
g
=
runtime_g
();
c
=
(
struct
cgoalloc
*
)
__go_alloc
(
sizeof
(
struct
cgoalloc
));
c
->
next
=
g
->
cgoalloc
;
c
->
alloc
=
ret
;
g
->
cgoalloc
=
c
;
return
ret
;
}
/* These are routines used by SWIG. The gc runtime library provides
the same routines under the same name, though in that case the code
is required to import runtime/cgo. */
...
...
@@ -16,7 +121,12 @@
void
*
_cgo_allocate
(
size_t
n
)
{
return
__go_alloc
(
n
);
void
*
ret
;
runtime_exitsyscall
();
ret
=
alloc_saved
(
n
);
runtime_entersyscall
();
return
ret
;
}
extern
const
struct
__go_type_descriptor
string_type_descriptor
...
...
@@ -30,13 +140,39 @@ _cgo_panic (const char *p)
struct
__go_string
*
ps
;
struct
__go_empty_interface
e
;
runtime_exitsyscall
();
len
=
__builtin_strlen
(
p
);
data
=
__go_alloc
(
len
);
data
=
alloc_saved
(
len
);
__builtin_memcpy
(
data
,
p
,
len
);
ps
=
__go_alloc
(
sizeof
*
ps
);
ps
=
alloc_saved
(
sizeof
*
ps
);
ps
->
__data
=
data
;
ps
->
__length
=
len
;
e
.
__type_descriptor
=
&
string_type_descriptor
;
e
.
__object
=
ps
;
/* We don't call runtime_entersyscall here, because normally what
will happen is that we will walk up the stack to a Go deferred
function that calls recover. However, this will do the wrong
thing if this panic is recovered and the stack unwinding is
caught by a C++ exception handler. It might be possible to
handle this by calling runtime_entersyscall in the personality
function in go-unwind.c. FIXME. */
__go_panic
(
e
);
}
/* Return the number of CGO calls. */
int64
runtime_NumCgoCall
(
void
)
__asm__
(
"runtime.NumCgoCall"
);
int64
runtime_NumCgoCall
(
void
)
{
int64
ret
;
M
*
m
;
ret
=
0
;
for
(
m
=
runtime_atomicloadp
(
&
runtime_allm
);
m
!=
NULL
;
m
=
m
->
alllink
)
ret
+=
m
->
ncgocall
;
return
ret
;
}
libgo/runtime/runtime.h
View file @
7bea4023
...
...
@@ -153,6 +153,9 @@ struct G
// uintptr sigpc;
uintptr
gopc
;
// pc of go statement that created this goroutine
int32
ncgo
;
struct
cgoalloc
*
cgoalloc
;
Traceback
*
traceback
;
ucontext_t
context
;
...
...
@@ -174,6 +177,7 @@ struct M
int32
profilehz
;
int32
helpgc
;
uint32
fastrand
;
uint64
ncgocall
;
Note
havenextg
;
G
*
nextg
;
M
*
alllink
;
// on allm
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment