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
Show 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()
...
@@ -10,3 +10,9 @@ func Entersyscall()
func
Exitsyscall
()
func
Exitsyscall
()
func
GetErrno
()
Errno
func
GetErrno
()
Errno
func
SetErrno
(
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 @@
...
@@ -4,11 +4,116 @@
Use of this source code is governed by a BSD-style
Use of this source code is governed by a BSD-style
license that can be found in the LICENSE file. */
license that can be found in the LICENSE file. */
#include "runtime.h"
#include "go-alloc.h"
#include "go-alloc.h"
#include "interface.h"
#include "interface.h"
#include "go-panic.h"
#include "go-panic.h"
#include "go-string.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
/* These are routines used by SWIG. The gc runtime library provides
the same routines under the same name, though in that case the code
the same routines under the same name, though in that case the code
is required to import runtime/cgo. */
is required to import runtime/cgo. */
...
@@ -16,7 +121,12 @@
...
@@ -16,7 +121,12 @@
void
*
void
*
_cgo_allocate
(
size_t
n
)
_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
extern
const
struct
__go_type_descriptor
string_type_descriptor
...
@@ -30,13 +140,39 @@ _cgo_panic (const char *p)
...
@@ -30,13 +140,39 @@ _cgo_panic (const char *p)
struct
__go_string
*
ps
;
struct
__go_string
*
ps
;
struct
__go_empty_interface
e
;
struct
__go_empty_interface
e
;
runtime_exitsyscall
();
len
=
__builtin_strlen
(
p
);
len
=
__builtin_strlen
(
p
);
data
=
__go_alloc
(
len
);
data
=
alloc_saved
(
len
);
__builtin_memcpy
(
data
,
p
,
len
);
__builtin_memcpy
(
data
,
p
,
len
);
ps
=
__go_alloc
(
sizeof
*
ps
);
ps
=
alloc_saved
(
sizeof
*
ps
);
ps
->
__data
=
data
;
ps
->
__data
=
data
;
ps
->
__length
=
len
;
ps
->
__length
=
len
;
e
.
__type_descriptor
=
&
string_type_descriptor
;
e
.
__type_descriptor
=
&
string_type_descriptor
;
e
.
__object
=
ps
;
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
);
__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
...
@@ -153,6 +153,9 @@ struct G
// uintptr sigpc;
// uintptr sigpc;
uintptr
gopc
;
// pc of go statement that created this goroutine
uintptr
gopc
;
// pc of go statement that created this goroutine
int32
ncgo
;
struct
cgoalloc
*
cgoalloc
;
Traceback
*
traceback
;
Traceback
*
traceback
;
ucontext_t
context
;
ucontext_t
context
;
...
@@ -174,6 +177,7 @@ struct M
...
@@ -174,6 +177,7 @@ struct M
int32
profilehz
;
int32
profilehz
;
int32
helpgc
;
int32
helpgc
;
uint32
fastrand
;
uint32
fastrand
;
uint64
ncgocall
;
Note
havenextg
;
Note
havenextg
;
G
*
nextg
;
G
*
nextg
;
M
*
alllink
;
// on allm
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